题目
http://acm.hdu.edu.cn/showproblem.php?pid=4790
分析
在[a,a+p-1]、[a+p,a+2*p-1]、... 与[c,c+p-1]、[c+p,c+2*p-1]...这些区间之间,直接乘法原理计算即可。
现在只考虑 [a',b] [c',d]这些区间中的答案。 将[a',d]所配对的答案区间[A,B]求出
这时只要看[A,B]与[c',d]的交集大小即可。
代码
#include<stdio.h> #include<stdlib.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; typedef long long int64; int64 a,b,c,d,p,m,dd,ans,fm; int T,test; int64 work(int64 l1,int64 r1,int64 l2,int64 r2) { if(l1>r1||l2>r2) return 0; int64 ll=(p+m-r1)%p,rr=(p+m-l1)%p; r2=(r2-l2+p)%p; ll=(ll-l2+p)%p; rr=(rr-l2+p)%p; if(ll<=rr) { if(r2<ll) return 0; return min(r2,rr)-ll+1; } int64 res=min(rr,r2)+1; res+=(r2-ll+1); return res; } int main() { // freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&p,&m); int l=a,r=b-(b-a+1)/p*p; int ll=c,rr=d-(d-c+1)/p*p; ans=(b-a+1)*((d-c+1)/p)+(d-c+1)*((b-a+1)/p)-((d-c+1)/p*p)*((b-a+1)/p); ans=ans+work(l,r,ll,rr); fm=(b-a+1)*(d-c+1); dd=__gcd(fm,ans); ans/=dd; fm/=dd; printf("Case #%d: %I64d/%I64d\n",++test,ans,fm); } return 0; }