想到了用容斥简化题目,也想倒如何去算大区间的方案,最后对两个遗留串处理纠结了太久!!
帅bin ac后我看了别人题解,真的只是细节讨论那儿处理的失误TAT
哎自己傻逼又没写出来!
1 #include2 #include 3 #include 4 using namespace std; 5 #define LL long long 6 LL p,m; 7 LL gcd(LL x,LL y) 8 { 9 if (y==0) return x;10 return gcd(y,x%y);11 }12 LL cal(LL a, LL b)13 {14 if(a < 0 || b < 0) return 0;15 LL k1=a%p,k2=b%p,ret;16 ret =(a/p)*(b/p)*p;17 ret+=(k1+1)*(b/p)+(k2+1)*(a/p);18 if(k1 > m)19 {20 ret+=min(m+1,k2+1);21 LL tmp=(m+p-k1)%p;22 if(tmp<=k2) ret+=k2-tmp+1;23 }24 else25 {26 LL tmp=(m-k1)%p;27 if(k2>=tmp) ret+=min(m-tmp+1,k2-tmp+1);28 }29 return ret;30 }31 int main()32 {33 LL T,t,a,b,c,d,ta,tz,g;34 scanf("%I64d",&T);35 for (t=1;t<=T;t++)36 {37 scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&p,&m);38 printf("Case #%I64d: ",t);39 tz=(b-a+1)*(d-c+1);40 if (a==0&&c==0) ta=cal(b,d);41 else if (a==0) ta=cal(b,d)-cal(b,c-1);42 else if (c==0) ta=cal(b,d)-cal(a-1,d);43 else ta=cal(b,d)-cal(a-1,d)-cal(b,c-1)+cal(a-1,c-1);44 45 g=gcd(tz,ta);46 if (ta==0) printf("0/1\n");47 else printf("%I64d/%I64d\n",ta/g,tz/g);48 }49 }