2

洛谷 P3373 【模板】线段树 2 题解

题目描述

如题,已知一个数列,你需要进行下面三种操作:

  • 将某区间每一个数乘上 x

  • 将某区间每一个数加上 x

  • 求出某区间每一个数的和

输入格式

第一行包含三个整数 n,m,p 分别表示该数列数字的个数、操作的总个数和模数。

第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。

接下来 m 行每行包含若干个整数,表示一个操作,具体如下:

操作 1: 格式:1 x y k 含义:将区间 [x,y] 内每个数乘上 k

操作 2: 格式:2 x y k 含义:将区间 [x,y] 内每个数加上 k

操作 3: 格式:3 x y 含义:输出区间 [x,y] 内每个数的和对 p 取模所得的结果

输出格式

输出包含若干行整数,即为所有操作 3 的结果。

AC代码:

注:记得开long long!!

  1 #include<bits/stdc++.h>
  2 #define ll long long
  3 using namespace std;
  4 
  5 int mod;
  6 ll n,m,a[5000001],add[5000001],mul[5000001];
  7 ll sum[5000001]; 
  8 
  9 void build(ll k,ll l,ll r)    
 10 {
 11     if (l==r)    
 12     {
 13         cin>>sum[k];
 14         sum[k]%=mod;
 15         return ;
 16     }
 17     ll mid=(l+r)>>1;
 18     build(k*2,l,mid); 
 19     build(k*2+1,mid+1,r);
 20     sum[k]=(sum[k*2]+sum[k*2+1])%mod; 
 21 }
 22 
 23 void Add(ll k,ll l,ll r,ll v)
 24 {
 25     add[k]=(add[k]+v)%mod;    
 26     sum[k]=(sum[k]+v*(r-l+1)%mod)%mod;
 27 }
 28 
 29 void Mul(ll k,ll v)
 30 {
 31     mul[k]=mul[k]%mod*v%mod;
 32     sum[k]=sum[k]%mod*v%mod;
 33     add[k]=add[k]%mod*v%mod;
 34 }
 35 
 36 void pushdown(ll k,ll l,ll r,ll mid) 
 37 {    
 38     if (mul[k]!=1)
 39     {
 40         Mul(k*2,mul[k]);     
 41         Mul(k*2+1,mul[k]);
 42         mul[k]=1;
 43     }
 44     if (add[k]!=0)    
 45     {
 46         Add(k*2,l,mid,add[k]);     
 47         Add(k*2+1,mid+1,r,add[k]);
 48         add[k]=0;
 49     }
 50 }
 51 
 52 ll query(ll k,ll l,ll r,ll x,ll y)     
 53 {
 54     if (x<=l&&r<=y)
 55         return sum[k];
 56     ll mid=(l+r)>>1;
 57     ll ans=0;
 58     pushdown(k,l,r,mid);
 59     if (x<=mid)
 60         ans=(ans+query(k*2,l,mid,x,y))%mod;
 61     if (mid<y)
 62         ans=(ans+query(k*2+1,mid+1,r,x,y))%mod;
 63     return ans;
 64 }
 65 
 66 void modify(ll k,ll l,ll r,ll x,ll y,ll v,ll op)     
 67 {
 68     if (x<=l&&r<=y)
 69     {
 70         if (op==1)
 71             return Mul(k,v);
 72         if (op==2)
 73             return Add(k,l,r,v);
 74     }
 75     ll mid=(l+r)>>1;
 76     pushdown(k,l,r,mid);    
 77     if (x<=mid)
 78         modify(k*2,l,mid,x,y,v,op);
 79     if (mid<y)
 80         modify(k*2+1,mid+1,r,x,y,v,op);
 81     sum[k]=(sum[k*2]+sum[k*2+1])%mod;  
 82 }
 83 
 84 int main()
 85 {
 86     scanf("%lld%lld%lld",&n,&m,&mod);
 87     for (ll i=1;i<=5000001;i++)
 88         mul[i]=1,add[i]=0;
 89     build(1,1,n);
 90     while (m--)
 91     {
 92         ll op,x,y,v;
 93         scanf("%lld",&op);
 94         if (op==1)     
 95         {
 96             scanf("%lld%lld%lld",&x,&y,&v);
 97             modify(1,1,n,x,y,v,1);
 98         }
 99         if (op==2)
100         {
101             scanf("%lld%lld%lld",&x,&y,&v);
102             modify(1,1,n,x,y,v,2);
103         }
104         if (op==3)    
105         {
106             scanf("%lld%lld",&x,&y);
107             printf("%lld\n",query(1,1,n,x,y)); 
108         } 
109     } 
110     return 0;
111 } 

 

posted @ 2021-08-18 11:19  Zˇx  阅读(44)  评论(0)    收藏  举报
Live2D