hdu4790 分别在两区间内各取一个数使模p为m的方案
想到了用容斥简化题目,也想倒如何去算大区间的方案,最后对两个遗留串处理纠结了太久!!
帅bin ac后我看了别人题解,真的只是细节讨论那儿处理的失误TAT
哎自己傻逼又没写出来!
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 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 else 25 { 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 }