[AH/HNOI2017]拋硬幣
題目描述
小 A 和小 B 是一對好朋友,他們經常一起愉快的玩耍。最近小 B 沈迷於**師手遊,天天刷本,根本無心搞學習。但是已經入坑了幾個月,卻一次都沒有抽到 SSR,讓他非常懷疑人生。勤勉的小 A 為了勸說小 B 早日脫坑,認真學習,決定以拋硬幣的形式讓小 B 明白他是一個徹徹底底的非洲人,從而對這個遊戲絕望。兩個人同時拋 b 次硬幣,如果小 A 的正面朝上的次數大於小 B 正面朝上的次數,則小 A 獲勝。
但事實上,小 A 也曾經沈迷過拉拉遊戲,而且他一次 UR 也沒有抽到過,所以他對於自己的運氣也沒有太大把握。所以他決定在小 B 沒註意的時候作弊,悄悄地多拋幾次硬幣,當然,為了不讓小 B 懷疑,他不會拋太多次。現在小 A 想問你,在多少種可能的情況下,他能夠勝過小 B 呢?由於答案可能太大,所以你只需要輸出答案在十進制表示下的最後 k 位即可。
輸入輸出格式
輸入格式:
有多組數據,對於每組數據輸入三個數a,b,k,分別代表小A拋硬幣的次數,小B拋硬幣的次數,以及最終答案保留多少位整數。
輸出格式:
對於每組數據,輸出一個數,表示最終答案的最後 k 位為多少,若不足 k 位以 0 補全。
輸入輸出樣例
輸入樣例#1: 復制2 1 9 3 2 1輸出樣例#1: 復制
000000004 6
說明
對於第一組數據,當小A拋2次硬幣,小B拋1次硬幣時,共有4種方案使得小A正面朝上的次數比小B多。
(01,0), (10,0), (11,0), (11,1)
對於第二組數據,當小A拋3次硬幣,小B拋2次硬幣時,共有16種方案使得小A正面朝上的次數比小B多。
(001,00), (010,00), (100,00), (011,00), (101,00), (110,00), (111,00), (011,01), (101,01), (110,01),(111,01), (011,10), (101,10), (110,10), (111,10), (111,11).
數據範圍
10%的數據滿足a,b≤20;
30%的數據滿足a,b≤100;
70%的數據滿足a,b≤100000,其中有20%的數據滿足a=b;
100%的數據滿足1\le a,b\le 10^{15},b\le a\le b+10000,1\le k\le 91≤a,b≤1015,b≤a≤b+10000,1≤k≤9,數據組數小於等於10。
暫時轉載http://www.cnblogs.com/Yuzao/p/7954245.html
因為 \(a-b\) 很小,考慮怎麽把式子變成和 \(a-b\) 有關.
考慮 \(a=b\) 的情況,考慮結果只有輸贏和平局三種,而且輸贏是對稱的,所以減去平局就是答案,所以答案為 \((2^{a+b}-C(2a,a))/2\).
\(a>b\) 時,同樣存在對稱性,對於正著會輸,反過來就贏得情況,就是 \(2^{a+b}/2\) 種
對於正著反著都贏的情況還沒有算進去:
\[\sum_{i=1}^{b}\sum_{j=1}^{a-b-1}C_{b}^{i}*C_{a}^{i+j}\]
\[\sum_{i=1}^{b}\sum_{j=1}^{a-b-1}C_{b}^{b-i}*C_{a}^{i+j}\]
\[\sum_{j=1}^{a-b-1}C_{a+b}^{b+j}\]
\[\sum_{j=b+1}^{a-1}C_{a+b}^{j}\]
對於除2,根據對稱性,只算一半即可,註意偶數情況,存在一項需要手動除2,算2時在因子中減去,算5時直接乘逆元即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long ll; 7 ll K,fac[6][2000001]; 8 ll exgcd(ll a,ll b,ll &x,ll &y) 9 { 10 if (b==0) 11 { 12 x=1;y=0; 13 return a; 14 } 15 ll d=exgcd(b,a%b,x,y); 16 ll t=x;x=y;y=t-(a/b)*x; 17 return d; 18 } 19 ll qpow(ll a,ll b,ll mod) 20 { 21 ll res=1; 22 while (b) 23 { 24 if (b&1) res=res*a%mod; 25 a=a*a%mod; 26 b/=2; 27 } 28 return res; 29 } 30 ll rev(ll a,ll b) 31 { 32 ll x,y; 33 exgcd(a,b,x,y); 34 return (x%b+b)%b; 35 } 36 ll calfac(ll x,ll p,ll t) 37 { 38 if (x<t) return fac[t][x]; 39 ll s=qpow(fac[t][p-1],x/p,p); 40 s=(s*fac[t][x%p])%p; 41 s=(s*calfac(x/t,p,t))%p; 42 return s; 43 } 44 ll lucas(ll b,ll a,ll t,ll p,bool q) 45 {ll i; 46 if (b<a) return 0; 47 ll ap=0,bp=0,cp=0; 48 for (i=b;i;i/=t) ap+=i/t; 49 for (i=a;i;i/=t) bp+=i/t; 50 for (i=b-a;i;i/=t) cp+=i/t; 51 ap=ap-bp-cp; 52 if (q==1&&t==2) ap--; 53 if (ap>=K) return 0; 54 ll s=qpow(t,ap,p); 55 ap=calfac(b,p,t);bp=calfac(a,p,t),cp=calfac(b-a,p,t); 56 s=((s*ap%p)*(rev(bp,p)*rev(cp,p))%p)%p; 57 if (q&&t==5) s=s*rev(2,p)%p; 58 return s; 59 } 60 ll cal(ll a,ll b,ll Mod,ll pr) 61 {ll i; 62 ll ans=qpow(2,a+b-1,Mod); 63 if (a==b) 64 { 65 ans=(ans-lucas(a+b,a,pr,Mod,1)+Mod)%Mod; 66 return ans; 67 } 68 else 69 { 70 for (i=(a+b)/2+1;i<a;i++) 71 ans=(ans+lucas(a+b,i,pr,Mod,0)+Mod)%Mod; 72 } 73 if ((a+b)%2==0) ans=(ans+lucas(a+b,(a+b)/2,pr,Mod,1)+Mod)%Mod; 74 return ans; 75 } 76 ll work(ll a,ll b,ll k) 77 { 78 ll p1=qpow(2,k,2e9+5),p2=qpow(5,k,2e9+5),mod=qpow(10,k,2e9+5); 79 ll b1=cal(a,b,p1,2),b2=cal(a,b,p2,5); 80 ll a1=rev(p2,p1),a2=rev(p1,p2); 81 return (b1*(p2*a1%mod)%mod+b2*(p1*a2%mod)%mod)%mod; 82 } 83 void print(ll d,ll k) 84 { 85 if (k==1) 86 printf("%01lld\n",d%qpow(10,1,2e9+5)); 87 if (k==2) 88 printf("%02lld\n",d%qpow(10,2,2e9+5)); 89 if (k==3) 90 printf("%03lld\n",d%qpow(10,3,2e9+5)); 91 if (k==4) 92 printf("%04lld\n",d%qpow(10,4,2e9+5)); 93 if (k==5) 94 printf("%05lld\n",d%qpow(10,5,2e9+5)); 95 if (k==6) 96 printf("%06lld\n",d%qpow(10,6,2e9+5)); 97 if (k==7) 98 printf("%07lld\n",d%qpow(10,7,2e9+5)); 99 if (k==8) 100 printf("%08lld\n",d%qpow(10,8,2e9+5)); 101 if (k==9) 102 printf("%09lld\n",d%qpow(10,9,2e9+5)); 103 } 104 int main() 105 {ll a,b,k,i,p; 106 fac[2][0]=1;p=qpow(2,9,2e9+5); 107 for (i=1;i<=p-1;i++) 108 if (i%2==0) fac[2][i]=fac[2][i-1]; 109 else fac[2][i]=fac[2][i-1]*i%p; 110 fac[5][0]=1;p=qpow(5,9,2e9+5); 111 for (i=1;i<=p-1;i++) 112 if (i%5==0) fac[5][i]=fac[5][i-1]; 113 else fac[5][i]=fac[5][i-1]*i%p; 114 while (cin>>a>>b>>k) 115 { 116 K=9;ll d=work(a,b,9); 117 print(d,k); 118 } 119 }
[AH/HNOI2017]拋硬幣