$\quad $ 主要式子:
\[(a+b)^{n} =\sum _{i=0}^{n}{C ^{i}_{n}}{a ^{i}b^{n-i}}
\]
P10185 [YDOI R1] Necklace
$\quad $ 非常好的一道二項式定理入門題,我們不去考慮所有可能的項鍊對答案產生的貢獻,而是去考慮每種珠子對答案產生的貢獻。
$\quad $ 記 \(sum=\sum _{i=1}^{n}a_i\) ,那麼對於每種珠子,除這種珠子以外的情況一共有 \(2^{sum-a_i}\) 種。再看這種珠子產生的貢獻,應為 \(\sum _{x=1}^{n}{C _{a_i}^{x}}{v_i ^{x}}\) 。
$\quad $ 在後面補一項 \(1 ^{a_i -x}\) ,即為:
\[\sum _{x=1}^{n}{C ^{x} _{a_i}}{v_i ^{x} 1 ^{a_i -x}}
\]
$\quad $ 然後就是一個裸的二項式定理(只不過去了一項 \(1\) ,加上再減去即可),就可以化為:
\[(v_i + 1)^{a_i} -1
\]
$\quad $ 所以最終答案為:
\[\sum _{i=1}^{n}{2 ^{sum -a_i}}[{(v_i +1) ^{a_i}-1] }]
\]
$\quad $ 時間複雜度 \(O(nlog(sum))\)
點選檢視程式碼
#define yhl 0
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+100,p=1e9+7;
int v[N],a[N],n,ans;
int qum(int a,int b){
int ans=1;
while(b){
(b&1)&&(ans=1ll*ans*a%p);
a=1ll*a*a%p;
b>>=1;
}
return ans;
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[yhl]+=a[i];
for(int i=1;i<=n;i++)scanf("%lld",&v[i]);
for(int i=1;i<=n;i++)
ans=(ans+1ll*qum(2,(a[yhl]-a[i]))*(qum(v[i]+1,a[i])-1+p)%p)%p;
printf("%lld",ans);
return yhl;
}