HDU 4790 Just Random (2013成都J题)
Just Random
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 87 Accepted Submission(s): 34
1. Coach Pang randomly choose a integer x in [a, b] with equal probability.
2. Uncle Yang randomly choose a integer y in [c, d] with equal probability.
3. If (x + y) mod p = m, they will go out and have a nice day together.
4. Otherwise, they will do homework that day.
For given a, b, c, d, p and m, Coach Pang wants to know the probability that they will go out.
For each test case, there is one line containing six integers a, b, c, d, p and m(0 <= a <= b <= 109, 0 <=c <= d <= 109, 0 <= m < p <= 109).
这题就是要找在[a,b] [c,d] 之间,和模p等于m的对数。
把[a,b] [c,d]所有可能组合的和写成下列形式。
a+c a+c+1 a+c+2 ..................a+d
a+c+1 a+c+2 a+c+3 ........a+d a+d+1
a+c+2 a+c+3 a+d a+d+1 a+d+2
....................
...................
b+c b+c+1 ...............................................b+d;
上面大致形成一个斜的矩阵。
使用b+c 和 a+d两条竖线,就可以分成三部分。前后两部分个数是等差数列,中间个数是相等的。
只需要讨论下b+c 和 a+d的大小。 然后找到%p==m 的位置,求和就可以搞定了。
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-16 13:20:40 4 File Name :E:\2013ACM\专题强化训练\区域赛\2013成都\1010.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 21 long long gcd(long long a,long long b) 22 { 23 if(b == 0)return a; 24 return gcd(b,a%b); 25 } 26 int main() 27 { 28 //freopen("in.txt","r",stdin); 29 //freopen("out.txt","w",stdout); 30 long long a,b,c,d,p,m; 31 int T; 32 int iCase = 0; 33 scanf("%d",&T); 34 while(T--) 35 { 36 iCase++; 37 scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&p,&m); 38 long long ans = 0; 39 if(b+c <= a+d) 40 { 41 long long t1 = (a+c)%p; 42 long long add = (m - t1 + p)%p; 43 long long cnt1 = (a+c + add-m)/p; 44 //cout<<t1<<" "<<add<<endl; 45 long long t2 = (b+c-1)%p; 46 long long sub = (t2 - m + p)%p; 47 long long cnt2 = (b+c-1-sub-m)/p; 48 //cout<<t2<<" "<<sub<<endl; 49 ans += (cnt2 - cnt1 + 1)*(1+add) + (cnt2 - cnt1 + 1)*(cnt2 - cnt1)/2 * p; 50 //printf("%I64d %I64d %I64d\n",cnt1,cnt2,ans); 51 t1 = (b+c)%p; 52 add = (m - t1 + p)%p; 53 cnt1 = (b+c+add-m)/p; 54 t2 = (a+d)%p; 55 sub = (t2 - m + p)%p; 56 cnt2 = (a+d-sub-m)/p; 57 ans += (cnt2 - cnt1 + 1)*(b-a+1); 58 t1 = (a+d+1)%p; 59 add = (m - t1 + p)%p; 60 cnt1 = (a+d+1+add-m)/p; 61 t2 = (b+d)%p; 62 sub = (t2 - m + p)%p; 63 cnt2 = (b+d-sub-m)/p; 64 ans += (cnt2 - cnt1 + 1)*(1+sub) + (cnt2 - cnt1 + 1)*(cnt2 - cnt1)/2*p; 65 } 66 else 67 { 68 long long t1 = (a+c)%p; 69 long long add = (m - t1 + p)%p; 70 long long cnt1 = (a+c + add-m)/p; 71 long long t2 = (a+d-1)%p; 72 long long sub = (t2 - m + p)%p; 73 long long cnt2 = (a+d-1-sub-m)/p; 74 ans += (cnt2 - cnt1 + 1)*(1+add) + (cnt2 - cnt1 + 1)*(cnt2 - cnt1)/2 * p; 75 t1 = (a+d)%p; 76 add = (m - t1 + p)%p; 77 cnt1 = (a+d+add-m)/p; 78 t2 = (b+ c)%p; 79 sub = (t2 - m + p)%p; 80 cnt2 = (b+c-sub-m)/p; 81 ans += (cnt2 - cnt1 + 1)*(d-c+1); 82 t1 = (b+c+1)%p; 83 add = (m - t1 + p)%p; 84 cnt1 = (b+c+1+add-m)/p; 85 t2 = (b+d)%p; 86 sub = (t2 - m + p)%p; 87 cnt2 = (b+d - sub-m)/p; 88 ans += (cnt2 - cnt1 + 1)*(1+sub) + (cnt2 - cnt1 + 1)*(cnt2 - cnt1)/2*p; 89 } 90 long long tot = (b-a+1)*(d-c+1); 91 long long GCD = gcd(ans,tot); 92 ans /= GCD; 93 tot /= GCD; 94 printf("Case #%d: %I64d/%I64d\n",iCase,ans,tot); 95 } 96 return 0; 97 }