hdu6829 | 杭電多校2020#6 T3 Borrow
阿新 • • 發佈:2020-08-06
標算是什麼亂七八糟的東西(
設 \(m=\frac{x+y+z}{3},x\ge y \ge z\)
注意到給錢的順序與最後的結果完全無關,所以可以讓原來最多的人先給出 \(x-m\) 元錢,此時會得到 \(m+a,m,m-a\) 的形式,其中 \(a\) 是一個不確定且可以列舉的數,這和 \(0,c,2c\) 是本質相同的。
設 \(f_x\) 表示 \(0,x,2x\) 狀態下的期望步數,則 \(f_x=x+\sum\limits_{i=0}^x \frac{1}{2^x}\binom{x}{i}f_i\) ,即原來是 \(2x\) 的人必須給出 \(x\) 元,並對結果分類討論,然後打表可得 \(f_x=2x\)
所以就做完了,(比標算好想好寫)
Code:
#include<bits/stdc++.h> using namespace std; #define mod 998244353 #define inf 0x3f3f3f3f inline int read() { char ch=getchar(); int nega=1; while(!isdigit(ch)) {if(ch=='-') nega=-1; ch=getchar();} int ans=0; while(isdigit(ch)) {ans=ans*10+ch-48;ch=getchar();} if(nega==-1) return -ans; return ans; } #define N 2000005 inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;} inline int mul(int x,int y){return 1LL*x*y%mod;} inline int mul(int x,int y,int z){return mul(mul(x,y),z);} int qpow(int x,int y) { int ans=1; while(y) { if(y&1) ans=mul(ans,x); x=mul(x,x); y>>=1; } return ans; } int Inv(int x){return qpow(x,mod-2);} int fac[N],inv[N],pinv[N],pw[N]; void init() { pw[0]=1; for(int i=1;i<N;i++) pw[i]=mul(pw[i-1],2); fac[0]=1; for(int i=1;i<N;i++) fac[i]=mul(fac[i-1],i); inv[0]=inv[1]=1; for(int i=2;i<N;i++) inv[i]=mul(mod-mod/i,inv[mod%i]); pinv[0]=1; for(int i=1;i<N;i++) pinv[i]=mul(pinv[i-1],inv[i]); } int C(int x,int y){return x>=y?mul(fac[x],pinv[x-y],pinv[y]):0;} int a[5]; void work() { for(int i=1;i<=3;i++) a[i]=read(); sort(a+1,a+4,[&](int x,int y){return x>y;}); if((a[1]+a[2]+a[3])%3!=0) { cout<<"-1\n"; return ; } int m=(a[1]+a[2]+a[3])/3,ans=0; for(int i=0;i<=(a[1]-m);i++) { int cur=abs(a[3]+i-m); ans=add(ans,mul(C(a[1]-m,i),cur*2)); } printf("%d\n",add(mul(ans,Inv(pw[a[1]-m])),a[1]-m)); } signed main() { init(); int T=read(); while(T--) work(); return 0; }