瞎搞。
把A分成P+P+…+P+lA~rA段
把B分成l1Br1B+P+P+…+P+l2Br2B段
A中有xA段P,B中有yB段P,两个长度为P的区间会产生P对,所以整数段将产生
这么多种组合。其余三段分情况讨论。(有可能B产生的分段不足P且在P分段之间,情况复杂,需耐心讨论)
#include <bits/stdc++.h>
using namespace std;
#define _int long long
_int a,b,c,d,p,m,B1,B2;
_int xA,yB;
_int lA,rA,l1B,r1B,l2B,r2B;
_int ans;
_int gcd(_int a,_int b){
if (a==0 || b==0) return a+b;
return gcd(b,a%b);
}
int fun(){
ans=0;
if (r1B-l1B > rA-lA){
ans = ans + (rA-lA)*(xA+1);
ans = ans + ((r1B-l1B)-(rA-lA))*(xA);
}
else ans = ans + (r1B-l1B)*(xA+1);
if ((r2B-l2B) > p-(rA-lA)){
ans = ans + (p-(rA-lA))*(xA);
ans = ans + ((r2B-l2B)-(p-(rA-lA)))*(xA+1);
}
else ans = ans + (r2B-l2B)*(xA);
ans = ans + (rA-lA) * (yB) ;
ans = ans + xA*yB*p;
return 0;
}
int main(){
_int T,Case=1;
scanf("%I64d",&T);
while (T--){
printf("Case #%I64d: ",Case++);
scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&d);
scanf("%I64d%I64d",&p,&m);
///part 0
c=c+p-m;
d=d+p-m;
_int fenmu=(b-a+1)*(d-c+1);
///part 1 确定B1
B1=(p-(a%p))%p;
if (B1<=d) B1=B1+(d-B1)/p*p;
while (B1<=d) B1=B1+p;
B1=B1-p;
B2=B1;
if (B2>=c) B2=B2-(B2-c)/p*p;
while (B2>=c) B2=B2-p;
B2=B2+p;
///part 2 找到A区间有多少P段长度 --> XA
/// 找到B区间有多少P段长度 --> XB
xA=(b+1-a)/p;
yB=(B1+1-c)/p;
///part 3 找到A的x+1区间左闭右开[x,y); 和B的两段y+1区间 左开右闭->左闭右开
lA=0;
rA=(b-a+1)%p;
l1B=p-(B2-c);
if (l1B==1) l1B=p+1;
r1B=p+1;
l2B=1;
r2B=(d-B1)%p+1;
if (B1 > d || B1 < c){
_int fa=p-c%p,ffa=fa,ffb,xx1,xx2,fffa,fffb,fff;
if (fa<a) ffa=fa+(a-fa)/p*p;
ffa=ffa-p-p;
while (ffa<a) ffa=ffa+p;
ffb=ffa-(d-c);
xx1=max(ffb,a);
xx2=min(ffa,b);
fffa=xx1;
if (fffa<b) fffa=fffa+(b-fffa)/p*p;
fffa=fffa-p-p;
while (fffa<=b) fffa=fffa+p;
fffa=fffa-p;
fffb=fffa+(xx2-xx1);
fff=min(b,fffb);
ans=(xx2-xx1+1)*((b-xx1)/p)+fff-fffa+1;
if (ans < 0){
printf("0/1\n");
continue;
}
_int anssg;
anssg=gcd(ans,fenmu);
if (anssg==0) anssg=1,fenmu=1;
printf("%I64d/%I64d\n",ans/anssg,fenmu/anssg);
continue;
}
fun();
_int anssg;
anssg=gcd(ans,fenmu);
if (anssg==0) anssg=1,fenmu=1;
printf("%I64d/%I64d\n",ans/anssg,fenmu/anssg);
}
return 0;
}