solution - P10045
注意到标题为线段树,所以这是一道线段树题。
因为
于是 pushup 解决了,线段树维护一个
同时给个
难点在于 pushdown。考虑如何更新
暴力展开,按照
即在
注意到后面那个括号里的和
先交换求和顺序:
令当前线段树区间长度为
于是得到:
把组合数拿出来,后面那一坨就可以替换为
于是就可以直接 pushdown 了。
至于 query,没必要查询区间的时候 merge,直接把每个查询到的线段树节点
复杂度是
然后取模是不需要的,可以用 unsigned 自然溢出实现
代码:
int n,Q,a[N],C[N][20];
class __segt
{
#define mid (l+r>>1)
#define lc v[pos<<1]
#define rc v[pos<<1|1]
#define lcp (pos<<1)
#define rcp (pos<<1|1)
private:
struct node{int f[20],tg;} v[N<<2];
int *a,n,lt,rt,k;
int mx;
il void pu(int len,int pos)
{
mx=min(len,(int)19);
rep(i,0,mx) v[pos].f[i]=0;
rep(i,0,mx) rep(j,0,mx-i) v[pos].f[i+j]+=lc.f[i]*rc.f[j];
}
int g[20],pw[20];
il void addtag(int len,int pos,int k)
{
v[pos].tg=(v[pos].tg+k),mx=min(len,(int)19);
pw[0]=1; rep(i,1,mx) pw[i]=pw[i-1]*k;
rep(i,0,mx)
{
g[i]=0;
rep(j,0,i) g[i]+=pw[i-j]*C[len-j][i-j]*v[pos].f[j];
}
rep(i,0,mx) v[pos].f[i]=g[i];
}
il void pd(int l,int r,int pos)
{
if(!v[pos].tg) return;
addtag(mid-l+1,lcp,v[pos].tg),addtag(r-mid,rcp,v[pos].tg);
v[pos].tg=0;
}
il void build(int l,int r,int pos)
{
if(l==r) return v[pos].f[0]=1,v[pos].f[1]=a[l]-1,void();
build(l,mid,lcp),build(mid+1,r,rcp);
pu(r-l+1,pos);
}
il void update(int l,int r,int pos)
{
if(l>=lt && r<=rt) return addtag(r-l+1,pos,k);
pd(l,r,pos);
lt<=mid && (update(l,mid,lcp),1),rt>mid && (update(mid+1,r,rcp),1);
pu(r-l+1,pos);
}
il int query(int l,int r,int pos)
{
if(l>=lt && r<=rt)
{
mx=min(r-l+1,(int)19);
int ans=0; rep(i,0,mx) ans+=v[pos].f[i];
return ans;
}
pd(l,r,pos);
return lt<=mid && rt>mid ? query(l,mid,lcp)*query(mid+1,r,rcp) : lt<=mid ? query(l,mid,lcp) : query(mid+1,r,rcp);
}
public:
il void bui(int *_a,int _n){a=_a,n=_n; build(1,n,1);}
il void upd(int l,int r,int _k){lt=l,rt=r,k=_k; update(1,n,1);}
il int q(int l,int r){lt=l,rt=r; return query(1,n,1);}
#undef mid
#undef lc
#undef rc
#undef lcp
#undef rcp
} tr;
il void solve()
{
read(n,Q),_::r(a,n);
{
C[0][0]=1;
rep(i,1,n) rep(j,0,19) C[i][j]=C[i-1][j]+(j?C[i-1][j-1]:0);
}
tr.bui(a,n);
int op,l,r,x;
while(Q--)
{
read(op,l,r);
if(op==1) read(x),x&&(tr.upd(l,r,x),1);
else write(tr.q(l,r)&1048575,'\n');
}
}
华风夏韵,洛水天依!