二项式定理做题记
$\quad $ 主要式子:
\[(a+b)^{n} =\sum _{i=0}^{n}{C ^{i}_{n}}{a ^{i}b^{n-i}}
\]
$\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;
}