BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树

来源:互联网 发布:java构造器 编辑:程序博客网 时间:2024/05/16 11:21

题意:链接

方法:线段树

解析:

俩标记sb题

更新乘的时候更新加

完了

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define N 100010using namespace std;typedef long long ll;ll mul[N<<2],sum[N<<2],add[N<<2];ll n,mod;int q;void pushup(int rt){    sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;}void pushdown(int rt,ll m){    if(mul[rt]!=1||add[rt]!=0)    {        mul[rt<<1]=(mul[rt<<1]*mul[rt])%mod;        mul[rt<<1|1]=(mul[rt<<1|1]*mul[rt])%mod;        add[rt<<1]=(mul[rt]*add[rt<<1]+add[rt])%mod;        add[rt<<1|1]=(mul[rt]*add[rt<<1|1]+add[rt])%mod;        sum[rt<<1]=(sum[rt<<1]*mul[rt]+(m-(m>>1))*add[rt])%mod;        sum[rt<<1|1]=(sum[rt<<1|1]*mul[rt]+(m>>1)*add[rt])%mod;        mul[rt]=1,add[rt]=0;    }}void build(int l,int r,int rt){    mul[rt]=1,sum[rt]=0;    if(l==r)    {        scanf("%I64d",&sum[rt]);        return;    }    int mid=(l+r)>>1;    build(lson),build(rson);    pushup(rt);}void update_mul(int L,int R,int l,int r,int rt,ll c){    if(L<=l&&r<=R)    {        mul[rt]=(mul[rt]*c)%mod;        add[rt]=(add[rt]*c)%mod;        sum[rt]=(sum[rt]*c)%mod;        return;    }    pushdown(rt,r-l+1);    int mid=(l+r)>>1;    if(L<=mid)update_mul(L,R,lson,c);    if(R>mid) update_mul(L,R,rson,c);    pushup(rt);}void update_add(int L,int R,int l,int r,int rt,ll c){    if(L<=l&&r<=R)    {        add[rt]=(add[rt]+c)%mod;        sum[rt]=(sum[rt]+(r-l+1)*c)%mod;        return;    }    pushdown(rt,r-l+1);    int mid=(l+r)>>1;    if(L<=mid)update_add(L,R,lson,c);    if(R>mid)update_add(L,R,rson,c);    pushup(rt);}ll query(int L,int R,int l,int r,int rt){    ll ret=0;    if(L<=l&&r<=R)    {        return sum[rt];    }    pushdown(rt,r-l+1);    int mid=(l+r)>>1;    if(L<=mid)ret=(ret+query(L,R,lson))%mod;    if(R>mid)ret=(ret+query(L,R,rson))%mod;    pushup(rt);    return ret;}int main(){    scanf("%lld%lld",&n,&mod);    build(1,n,1);    scanf("%d",&q);    while(q--)    {        int opt;scanf("%d",&opt);        int x,y;scanf("%d%d",&x,&y);        ll z;        switch(opt)        {            case 1:scanf("%lld",&z);update_mul(x,y,1,n,1,z);break;            case 2:scanf("%lld",&z);update_add(x,y,1,n,1,z);break;            case 3:printf("%lld\n",query(x,y,1,n,1));break;        }    }}
0 0