洛谷 P3373 【模板】线段树 2 区间加、区间乘

  1 #include<bits/stdc++.h>
  2 #define ls (x<<1)
  3 #define rs (x<<1|1)
  4 #define rep(i,a,b) for(int i=a;i<=b;i++)
  5 #define pb(a) push_back(a)
  6 using namespace std;
  7 typedef long long ll;
  8 typedef pair<int,int> pii;
  9 const int N=1e5+5;
 10 int n,m,p;
 11 ll sum[N<<2],addtag[N<<2],multag[N<<2],a[N];
 12 void update(int x)
 13 {
 14     sum[x]=(sum[ls]+sum[rs])%p;
 15 }
 16 void down(int l,int r,int x)
 17 {
 18     int mid=(l+r)>>1;
 19     if(addtag[x]||multag[x]!=1)
 20     {
 21         addtag[ls]=(addtag[ls]*multag[x]+addtag[x])%p;
 22         addtag[rs]=(addtag[rs]*multag[x]+addtag[x])%p;
 23         multag[ls]=(1ll*multag[ls]*multag[x])%p;
 24         multag[rs]=(1ll*multag[rs]*multag[x])%p;
 25         sum[ls]=(sum[ls]*multag[x]+(mid-l+1)*addtag[x])%p;
 26         sum[rs]=(sum[rs]*multag[x]+(r-mid)*addtag[x])%p;
 27         
 28         multag[x]=1;
 29         addtag[x]=0;
 30     }
 31 }
 32 void build(int l,int r,int x)
 33 {
 34     if(l==r)
 35     {
 36         sum[x]=a[l]%p;
 37         return;
 38     }
 39     int mid=(l+r)>>1;
 40     build(l,mid,ls);
 41     build(mid+1,r,rs);
 42     update(x);
 43 }
 44 void modify(int A,int B,int l,int r,int v,int op,int x)
 45 {
 46     if(A<=l&&B>=r)
 47     {
 48       if(op==1)
 49       {
 50           sum[x]=(sum[x]*v)%p;
 51           multag[x]=(1ll*multag[x]*v)%p;
 52           addtag[x]=(1ll*addtag[x]*v)%p;
 53       }
 54       else 
 55       {
 56           sum[x]=(sum[x]+v*(r-l+1))%p;
 57           addtag[x]=(addtag[x]+v)%p;
 58       }
 59       return ;
 60     }
 61     down(l,r,x);
 62     int mid=(l+r)>>1;
 63     if(A<=mid)modify(A,B,l,mid,v,op,ls);
 64     if(B>mid)modify(A,B,mid+1,r,v,op,rs);
 65     update(x);
 66 }
 67 ll query(int A,int B,int l,int r,int x)
 68 {
 69     if(A<=l&&B>=r)return sum[x];
 70     down(l,r,x);
 71     ll mid=(l+r)>>1,ret=0;
 72     if(A<=mid)ret+=query(A,B,l,mid,ls);
 73     if(B>mid)ret+=query(A,B,mid+1,r,rs);
 74     return ret%p;
 75 }
 76 int main()
 77 {
 78     /*
 79     freopen("P3373_1.in","r",stdin);
 80     freopen("answer.txt","w",stdout);
 81     */
 82     scanf("%d%d%d",&n,&m,&p);
 83     rep(i,1,n)
 84     scanf("%d",&a[i]);
 85     build(1,n,1);
 86     for(int i=1;i<=4*n;i++)multag[i]=1;
 87     rep(i,1,m)
 88     {
 89         int op;
 90         scanf("%d",&op);
 91         if(op==1)
 92         {
 93             int l,r,v;
 94             scanf("%d%d%d",&l,&r,&v);
 95             modify(l,r,1,n,v,1,1);    
 96         }
 97         else if(op==2)
 98         {
 99             int l,r,v;
100             scanf("%d%d%d",&l,&r,&v);
101             modify(l,r,1,n,v,2,1);
102         }
103         else 
104         {
105             int l,r;
106             scanf("%d%d",&l,&r);
107             printf("%lld\n",query(l,r,1,n,1));
108         }
109     
110     }
111     return 0;
112 }

 

posted @ 2022-01-07 21:44  matt-11  阅读(43)  评论(0)    收藏  举报