using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("2");
WillReturn.Add("1 2");
WillReturn.Add("1 2");
//0.250000000000
}
else if (InputPattern == "Input2") {
WillReturn.Add("3");
WillReturn.Add("3 3");
WillReturn.Add("1 1");
WillReturn.Add("4 4");
//1.000000000000
}
else if (InputPattern == "Input3") {
WillReturn.Add("10");
WillReturn.Add("1 10");
WillReturn.Add("38 40");
WillReturn.Add("8 87");
WillReturn.Add("2 9");
WillReturn.Add("75 100");
WillReturn.Add("45 50");
WillReturn.Add("89 92");
WillReturn.Add("27 77");
WillReturn.Add("23 88");
WillReturn.Add("62 81");
//13.696758921226
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct LRInfoDef
{
internal int L;
internal int R;
}
static List<LRInfoDef> mLRInfoList = new List<LRInfoDef>();
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
LRInfoDef WillAdd;
WillAdd.L = wkArr[0];
WillAdd.R = wkArr[1];
mLRInfoList.Add(WillAdd);
}
// 個数の期待値[値]なフェニック木
int UB = mLRInfoList.Max(pX => pX.R);
var Ins_Fenwick_Tree = new Fenwick_Tree(UB + 1);
double Answer = 0;
foreach (LRInfoDef EachLRInfo in mLRInfoList) {
double RangeLen = EachLRInfo.R - EachLRInfo.L + 1;
for (int I = EachLRInfo.L; I <= EachLRInfo.R; I++) {
if (I < UB) {
double Ex = Ins_Fenwick_Tree.GetSum(I + 1, UB, true);
Ex *= 1 / RangeLen;
Answer += Ex;
}
}
for (int I = EachLRInfo.L; I <= EachLRInfo.R; I++) {
Ins_Fenwick_Tree.Add(I, 1 / RangeLen, true);
}
}
Console.WriteLine(Answer);
}
}
#region Fenwick_Tree
// フェニック木
internal class Fenwick_Tree
{
private double[] mBitArr;
private int mN;
// コンストラクタ
internal Fenwick_Tree(int pItemCnt)
{
mN = pItemCnt;
mBitArr = new double[pItemCnt + 1];
}
// [pSta,pEnd] のSumを返す
internal double GetSum(int pSta, int pEnd, bool pIsZeroOrigin)
{
return GetSum(pEnd, pIsZeroOrigin) - GetSum(pSta - 1, pIsZeroOrigin);
}
// [0,pEnd] のSumを返す
internal double GetSum(int pEnd, bool pIsZeroOrigin)
{
if (pIsZeroOrigin) {
pEnd++; // 1オリジンに変更
}
double Sum = 0;
while (pEnd >= 1) {
Sum += mBitArr[pEnd];
pEnd -= pEnd & -pEnd;
}
return Sum;
}
// [I] に Xを加算
internal void Add(int pI, double pX, bool pIsZeroOrigin)
{
if (pIsZeroOrigin) {
pI++; // 1オリジンに変更
}
while (pI <= mN) {
mBitArr[pI] += pX;
pI += pI & -pI;
}
}
}
#endregion