http://codeforces.com/contest/266/problem/E
题意明显,略掉。把表达式展开,其中i一项,(1-l)一项,根据二项式定理展开,发现只需要维护a[i]*i^k,0<=k<6,注意k=0的情况。。一共6棵树,由于有成端更新,而且可以更新为0,标记要初始化为-1,反正涉及到0的地方注意吧,细节比较多。。。这道题其实还是很好想的,但想起来比较费劲,代码能力真心渣的不多说。。。。刚开始还维护量搞错了,T……T。。。。附代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cmath>
#define N 100004
#define cl(a) memset(a,0,sizeof(a))
#define lson l,m,rt<<1,k
#define rson m+1,r,rt<<1|1,k
#define ss(a) scanf("%d",&a)
#define mod 1000000007
#define ll __int64
using namespace std;
int col[6][N<<2],a[N],c[7][7];
ll tre[6][N<<2],f[6][N];
ll powing(int x,int k)
{
if (x==0) return 0;
ll res=1;
for (int i=1;i<=k;i++) res=((res*x)%mod+mod)%mod;
return res;
}
void init()
{
int i,j;
for (i=0;i<6;i++)
for (j=0;j<=i;j++)
{
if (j==0) c[i][j]=1;
else if (j>i-j) c[i][j]=c[i][i-j];
else c[i][j]=c[i-1][j-1]+c[i-1][j];
}
for (i=1;i<N;i++)
for (j=0;j<6;j++)
{
f[j][i]=(f[j][i-1]+powing(i,j))%mod;
}
}
void pushup(int rt,int k)
{
tre[k][rt]=(tre[k][rt<<1]+tre[k][rt<<1|1])%mod;
}
void build(int l,int r,int rt,int k)
{
if (l==r)
{
tre[k][rt]=powing(l,k)*a[l]%mod;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt,k);
}
void pushdown(int l,int r,int rt,int k)
{
if (col[k][rt]!=-1)
{
int m=(l+r)>>1,x=col[k][rt];
tre[k][rt<<1]=((f[k][m]-f[k][l-1]+mod)%mod)*x%mod;
tre[k][rt<<1|1]=((f[k][r]-f[k][m]+mod)%mod)*x%mod;
col[k][rt<<1]=col[k][rt<<1|1]=col[k][rt];
col[k][rt]=-1;
}
}
void update(int x,int L,int R,int l,int r,int rt,int k)
{
if (L<=l&&r<=R)
{
tre[k][rt]=x*(f[k][r]-f[k][l-1]+mod)%mod;
col[k][rt]=x;
return;
}
pushdown(l,r,rt,k);
int m=(l+r)>>1;
if (L<=m) update(x,L,R,lson);
if (R>m) update(x,L,R,rson);
pushup(rt,k);
}
ll query(int L,int R,int l,int r,int rt,int k)
{
if (L<=l&&r<=R)
{
return tre[k][rt];
}
pushdown(l,r,rt,k);
int m=(l+r)>>1;
ll res=0;
if (L<=m) res=(res+query(L,R,lson))%mod;
if (R>m) res=(res+query(L,R,rson))%mod;
return res;
}
int main()
{
int i,l,r,x,k,n,m,j;
init();
ss(n);ss(m);
for (i=1;i<=n;i++) ss(a[i]);
memset(col,-1,sizeof(col));
for (i=0;i<6;i++) build(1,n,1,i);
for (i=1;i<=m;i++)
{
char ch;
cin>>ch;
ss(l);ss(r);
if (ch=='=')
{
ss(x);
for (j=0;j<6;j++) update(x,l,r,1,n,1,j);
}
else
{
ss(k);
ll res=0;
if (l==1)
{
res=query(l,r,1,n,1,k);
}
else
{
for (j=0;j<=k;j++)
{
//cout<<query(l,r,1,n,1,j)<<endl;
res=(res+(query(l,r,1,n,1,j)*powing(1-l,k-j)%mod)*c[k][j]%mod)%mod;
}
}
printf("%d\n",res);
}
}
return 0;
}