首先肯定想到二分。。。然而j精度问题。。。那就看你自己的造化了。二分得出一个每个人的(步长)然后再枚举+来一次二分就可以了(其实直接算就好了)
#include <set>
#include <map>
#include <queue>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <bitset>
#include <cstring>
#include <cstdlib>
#include <utility>
#include <iostream>
#include <algorithm>
#define REP(i,a,b) for(int i=(a);i<=(b);i++)
#define PER(i,a,b) for(int i=(a);i>=(b);i--)
#define RVC(i,S) for(int i=0;i<(S).size();i++)
#define RAL(i,u) for(int i=fr[u];i!=-1;i=e[i].next)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
template<class T> inline
void read(T& num) {
bool start=false,neg=false;
char c;
num=0;
while((c=getchar())!=EOF) {
if(c=='-') start=neg=true;
else if(c>='0' && c<='9') {
start=true;
num=num*10+c-'0';
} else if(start) break;
}
if(neg) num=-num;
}
/*============ Header Template ============*/
const int maxn=(int)(1e5)+5;
const double eps=1e-10;
int s[maxn],e[maxn],rk[maxn];
int n;
inline bool cmp(int i,int j) {
if(s[i]!=s[j]) return s[i]<s[j];
return e[i]<e[j];
}
inline bool solve(double x) {
int pos=0;double now=0;
REP(i,1,n) {
int k=rk[i];
if(s[k]>pos) {
pos=s[k];now=0;
}
double p=x;
double dt=min(p,1-now);
now+=dt;p-=dt;
if(fabs(now-1)<eps) pos++,now=0;
if(pos>e[k]) return 0;
if(fabs(p)<eps) continue;
dt=(int)ceil(p+eps)-1;
pos+=dt;p-=dt;now=p;
if(pos>e[k] || (pos==e[k]+1 && fabs(now)>eps)) return 0;
}
return 1;
}
inline void chk(double x,LL& ax,LL& ay,LL cx,LL cy) {
if(fabs(1.0*cx/cy-x)<fabs(1.0*ax/ay-x)) ax=cx,ay=cy;
}
inline void print(double x) {
LL ax=1,ay=1;
REP(i,1,n) {
if(x*i>1e18) break;
LL s=(LL)(x*i+0.5);
chk(x,ax,ay,s,i);
}
printf("%lld/%lld\n",ax,ay);
}
void cases() {
int mi=0;
read(n);
REP(i,1,n) {
read(s[i]);read(e[i]);e[i]--;rk[i]=i;mi=e[i]-s[i]+1;
}
sort(rk+1,rk+n+1,cmp);
if(mi==0) {
printf("0/1\n");
return;
}
double l=0,r=mi,mid;
while(fabs(r-l)>eps) {
mid=(l+r)/2;
if(solve(mid)) l=mid;
else r=mid;
}
print(mid);
}
int main() {
int T;
read(T);
while(T--) cases();
return 0;
}