如
0 5 0 5 3 0
这组数据,把较长的区间放在前面。
这样一定有构成的和
0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
5 6 7 8 9 10
前后各一个等差数列中间一个常数列,分开求和即可。
把较长的放前面,的原因, 这样一来,前后各一个lenb-1长度的等差,中间一个常数列,不用再分情况讨论。
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,x,y) for(int i=x;i<=(int)y;i++)
typedef long long ll;
int a,b,c,d,p,m;
int cal(int x){
if(x==-1) return 0;
return (x+1)/p+((x+1)%p>=(m+1) ? 1:0);
}
ll query(int x,int y){return cal(y)-cal(x-1); }
ll fir(int x,int y){
if(x%p > m) return (ll)1+(p-x%p)+m;
return (ll)1+(m-x%p);
}
ll gcd(ll a,ll b){return (b==0 ? a:gcd(b,a%b)); }
int main()
{
int T,kase=1;
scanf("%d",&T);
while(T--){
scanf("%d %d %d %d %d %d",&a,&b,&c,&d,&p,&m);
if(b-a < d-c){ swap(a,c),swap(b,d);}
ll ans = 0 ,x,y,x1,y1, lena = b-a+1,lenb=d-c+1;
x = a+c; y=x+(lenb-1)-1;
y1 = b+d; x1 = y1-(lenb-1)+1;
int l = y+1, r = x1-1;
ans += query(l,r)*lenb;
ans += (fir(x,y)+fir(x,y)+(query(x,y)-1)*p)*(query(x,y))/2;
ans += ((lenb-fir(x1,y1))*2-(query(x1,y1)-1)*p)*(query(x1,y1))/2;
ll fenm = lena*lenb , g=gcd(fenm,ans);
ans/=g; fenm/=g;
printf("Case #%d: %I64d/%I64d\n",kase++,ans,fenm);
}
return 0;
}