bzoj1798: [Ahoi2009]Seq 维护序列seq

来源:互联网 发布:淘宝蜜琪美妆是假货吗 编辑:程序博客网 时间:2024/06/02 06:42

bzoj1798: [Ahoi2009]Seq 维护序列seq
又一道裸线段树。
交上去一直RERERE,调了半天发现把叶子节点pushdown了可不RE。真是代码力低下。
直接上AC代码。


代码

#include<iostream>#include<cstdio>#define mxn 100016using namespace std;int n,m,a[mxn],x,y,p,op,val;int ll[mxn<<2],rr[mxn<<2];long long ad[mxn<<2],mu[mxn<<2],sum[mxn<<2];void update(int k){sum[k]=(sum[k<<1]+sum[k<<1|1])%p;}void build(int k,int l,int r){    ll[k]=l,rr[k]=r,ad[k]=0,mu[k]=1;    if(l==r)sum[k]=a[l]%p;    else    {        int mid=(l+r)>>1;        build(k<<1,l,mid),build(k<<1|1,mid+1,r);        update(k);    }}void pushdown(int k){    mu[k<<1]=(mu[k<<1]*mu[k])%p,mu[k<<1|1]=(mu[k<<1|1]*mu[k])%p;    ad[k<<1]=(ad[k]+ad[k<<1]*mu[k])%p,ad[k<<1|1]=(ad[k]+ad[k<<1|1]*mu[k])%p;    sum[k<<1]=(sum[k<<1]*mu[k]%p+ad[k]*(rr[k<<1]-ll[k<<1]+1))%p;    sum[k<<1|1]=(sum[k<<1|1]*mu[k]%p+ad[k]*(rr[k<<1|1]-ll[k<<1|1]+1))%p;    ad[k]=0,mu[k]=1;}void add(int k,int l,int r,int v){    sum[k]=(sum[k]+v*(r-l+1))%p;    if(ll[k]==l&&rr[k]==r)    ad[k]=(ad[k]+v)%p;    else    {        pushdown(k);        int mid=(ll[k]+rr[k])>>1;        if(l>mid)add(k<<1|1,l,r,v);        else if(r<=mid)add(k<<1,l,r,v);        else add(k<<1,l,mid,v),add(k<<1|1,mid+1,r,v);    }}void mul(int k,int l,int r,int v){    if(ll[k]!=rr[k])    pushdown(k);    if(ll[k]==l&&rr[k]==r)    sum[k]=sum[k]*v%p,mu[k]=mu[k]*v%p;    else    {        int mid=(ll[k]+rr[k])>>1;        if(l>mid)mul(k<<1|1,l,r,v);        else if(r<=mid)mul(k<<1,l,r,v);        else mul(k<<1,l,mid,v),mul(k<<1|1,mid+1,r,v);        update(k);    }}int qry(int k,int l,int r){    if(ll[k]==l&&rr[k]==r)return sum[k];    pushdown(k);    int mid=(ll[k]+rr[k])>>1;    if(l>mid)return qry(k<<1|1,l,r);    else if(r<=mid)return qry(k<<1,l,r);    else return(qry(k<<1,l,mid)+qry(k<<1|1,mid+1,r))%p;}int main(){    scanf("%d%d",&n,&p);    for(int i=1;i<=n;i++)    scanf("%d",&a[i]);    build(1,1,n);    scanf("%d",&m);    while(m--)    {        scanf("%d%d%d",&op,&x,&y);        if(op==1)        scanf("%d",&val),mul(1,x,y,val%p);        else if(op==2)        scanf("%d",&val),add(1,x,y,val%p);        else printf("%d\n",qry(1,x,y));    }}
1 0
原创粉丝点击