【找規律】【遞推】【二項式定理】Codeforces Round #419 (Div. 1) B. Karen and Test
阿新 • • 發佈:2017-06-18
main turn logs pow 分享 string ren () 奇數
打個表出來看看,其實很明顯。
推薦打這倆組
11
1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 10000000000
12
1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 10000000000 100000000000
打出表來看出來,n為偶數時,每隔兩行,對原序列的奇數項分配的權重形成二項展開式。
n為奇數時,每隔四行,形成二項展開式。
所以只需要求出接近最後的某一行中的二項式系數即可。(有個O(n)的遞推式可以直接求楊輝三角某一行的值)
最後距離答案已經不超過四行了,暴一下就行了。
#include<cstdio> #include<cstring> using namespace std; #define MOD 1000000007ll typedef long long ll; ll n,nn; ll a[200010],C[200010],b[10],c[10]; ll Quick_Pow(ll a,ll p) { if(!p) return 1; ll ans=Quick_Pow(a,p>>1); ans=ans*ans%MOD; if((p&1)==1) ans=(a%MOD*ans)%MOD; return ans; } int main(){ scanf("%I64d",&n); for(ll i=1ll;i<=n;++i){ scanf("%I64d",&a[i]); } int tmp=0; if(!(n&1ll)){ nn=n/2ll-1ll; tmp=2; } else{ nn=n; ++tmp; while((nn-1ll)%4ll!=0ll){ --nn; ++tmp; } nn/=2ll; } C[0]=1; for(ll i=1ll;i<=nn;++i){ C[i]=((C[i-1]*(nn-(i-1ll)))%MOD*Quick_Pow(i,MOD-2ll))%MOD; } for(int i=1;i<=tmp;++i){ for(int j=i,k=0;j<=n;j+=2,++k){ b[i]=(b[i]+(a[j]%MOD*C[k])%MOD)%MOD; } } ll sum=0; for(ll i=n;i>(ll)tmp;--i){ sum+=(i-1ll); } bool op=(sum%2ll==0 ? 1 : 0); for(int i=tmp;i>1;--i){ for(int j=1;j<i;++j){ if(op){ c[j]=b[j]+b[j+1]; } else{ c[j]=b[j]-b[j+1]; } op^=1; } memcpy(b,c,sizeof(c)); } printf("%I64d\n",(b[1]+MOD)%MOD); return 0; }
【找規律】【遞推】【二項式定理】Codeforces Round #419 (Div. 1) B. Karen and Test