[bzoj1798][Ahoi2009]Seq 维护序列seq

题意:给定一个序列,要支持区间加,区间乘,区间求和   $n,m\leqslant 100000$

题解:线段树练练手

#include<iostream>
#include<cstdio>
#define MN 100000
#define ll long long
using namespace std;
inline int read()
{
    int x = 0 , f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}

int n,m,s[MN+5],mod;
struct TREE{
    int l,r;ll x,ad,val;
}T[MN*8+5];

void pushdown(int x)
{
    int l=x<<1,r=x<<1|1;
    if(T[x].val!=1)
    {
        T[l].ad*=T[x].val;T[r].ad*=T[x].val;
        T[l].val*=T[x].val;T[r].val*=T[x].val;
        T[l].ad%=mod;T[r].ad%=mod; 
        T[l].val%=mod;T[r].val%=mod;
    }
    if(T[x].ad)
    {
        T[l].ad=(T[l].ad+T[x].ad)%mod;
        T[r].ad=(T[r].ad+T[x].ad)%mod;
    }
    T[l].x=(T[l].x*T[x].val%mod+1LL*(T[l].r-T[l].l+1)*T[x].ad)%mod;
    T[r].x=(T[r].x*T[x].val%mod+1LL*(T[r].r-T[r].l+1)*T[x].ad)%mod;
    T[x].val=1;T[x].ad=0;
}

void build(int x,int l,int r)
{
    T[x].val=1;
    if((T[x].l=l)==(T[x].r=r)) {T[x].x=s[l];return;}
    int mid=l+r>>1;
    build(x<<1,l,mid);build(x<<1|1,mid+1,r);
    T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;
}

void modify(int x,int l,int r,ll ad)
{
     pushdown(x);
    if(T[x].l==l&&T[x].r==r)
    {
        T[x].ad+=ad;T[x].x+=1LL*(r-l+1)*ad;
        T[x].x%=mod;T[x].ad%=mod;
        return;
    }
    int mid=T[x].l+T[x].r>>1;
    if(r<=mid)modify(x<<1,l,r,ad);
    else if(l>mid) modify(x<<1|1,l,r,ad);
    else {modify(x<<1,l,mid,ad);modify(x<<1|1,mid+1,r,ad);}
    T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;
}

void renew(int x,int l,int r,ll val)
{
    pushdown(x);
    if(T[x].l==l&&T[x].r==r)
    {
        T[x].val*=val;T[x].val%=mod;
        T[x].x*=val;T[x].x%=mod;
        return;
    }
    int mid=T[x].l+T[x].r>>1;
    if(r<=mid)renew(x<<1,l,r,val);
    else if(l>mid) renew(x<<1|1,l,r,val);
    else {renew(x<<1,l,mid,val);renew(x<<1|1,mid+1,r,val);}
    T[x].x=(T[x<<1].x+T[x<<1|1].x)%mod;
}

ll query(int x,int l,int r)
{
     pushdown(x);
    if(T[x].l==l&&T[x].r==r)return T[x].x;
    int mid=T[x].l+T[x].r>>1;
    if(r<=mid) return query(x<<1,l,r);
    else if(l>mid) return query(x<<1|1,l,r);
    else return (query(x<<1,l,mid)+query(x<<1|1,mid+1,r))%mod;
}

int main()
{
    n=read();mod=read();
    for(int i=1;i<=n;i++)s[i]=read();
    build(1,1,n);
    m=read();
    for(int i=1;i<=m;i++)
    {
        int op=read(),l=read(),r=read();
        if(op==3) printf("%d\n",(int)query(1,l,r));
        else 
        {
            int x=read();
            if(op==2) modify(1,l,r,x);
            else renew(1,l,r,x); 
        } 
    }
    return 0;
}

 

posted @ 2017-03-28 14:00  FallDream  阅读(161)  评论(0编辑  收藏  举报