题目描述
给你(n,k,a_1ldots a_n),设
[ans_n=sum_{i=1}^n{(sum_{j=i}^ns(j))}^k\
]
求(ans_1ldots ans_n)
对({10}^9+7)取模
(nleq 50000,kleq 100)
题解
大水题
这题就是在搞笑
题解的做法是(O(nklog k))的
随便推推就能推出(O(nk))的做法
[egin{align}
ans_n&=sum_{i=1}^n{(sum_{j=i}^ns(j))}^k\
&=sum_{i=1}^n{(s_n-s_{i-1})}^k\
&=sum_{i=1}^nsum_{j=0}^k{s_n}^{j}{s_{i-1}}^{k-j}{(-1)}^{k-j}inom{k}{j}\
&=sum_{i=0}^k{s_n}^i{(-1)}^{k-i}inom{k}{i}sum_{j=1}^n{s_{j-1}}^{k-i}
end{align}
]
维护最后那项即可。
时间复杂度:(O(nk))
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll p=1000000007;
ll c[110][110];
ll a[50010];
ll s[50010];
ll b[50010];
int main()
{
#ifndef ONLINE_JUDGE
freopen("xsy2032.in","r",stdin);
freopen("xsy2032.out","w",stdout);
#endif
int n,k;
scanf("%d%d",&n,&k);
int i,j;
memset(c,0,sizeof c);
for(i=0;i<=k;i++)
{
c[i][0]=1;
for(j=1;j<=i;j++)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%p;
}
b[0]=1;
s[0]=1;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
a[i]=(a[i]+a[i-1])%p;
for(j=1;j<=k;j++)
b[j]=b[j-1]*a[i]%p;
ll ans=0;
for(j=0;j<=k;j++)
ans=(ans+b[j]*s[k-j]%p*c[k][j]%p*((k-j)&1?-1:1))%p;
ans=(ans+p)%p;
printf("%lld
",ans);
for(j=0;j<=k;j++)
s[j]=(s[j]+b[j])%p;
}
return 0;
}