luogu P3373 模板线段树 2
Posted ZYBGMZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P3373 模板线段树 2相关的知识,希望对你有一定的参考价值。
题目描述
如题,已知一个数列,你需要进行下面两种操作:
1.将某区间每一个数加上x
2.将某区间每一个数乘上x
3.求出某区间每一个数的和
输入输出格式
输入格式:
第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k
操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k
操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果
输出格式:
输出包含若干行整数,即为所有操作3的结果。
输入输出样例
输入样例#1:
5 5 38 1 5 4 2 3 2 1 4 1 3 2 5 1 2 4 2 2 3 5 5 3 1 4
输出样例#1:
17 2
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=1000,M<=10000
对于100%的数据:N<=100000,M<=100000
(数据已经过加强^_^)
样例说明:
故输出应为17、2(40 mod 38=2)
需要越来越习惯lazy-tag的使用才行啊
tag1表示乘,tag2表示加
线段树的写法真是各有各的风格 大雾
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 6 typedef long long ll; 7 8 inline int read(){ 9 char ch; 10 int re=0; 11 bool flag=0; 12 while((ch=getchar())!=‘-‘&&(ch<‘0‘||ch>‘9‘)); 13 ch==‘-‘?flag=1:re=ch-‘0‘; 14 while((ch=getchar())>=‘0‘&&ch<=‘9‘) re=re*10+ch-‘0‘; 15 return flag?-re:re; 16 } 17 18 struct segment{ 19 int l,r; 20 ll sum,tag1,tag2; 21 segment(){ 22 sum=0; 23 tag1=1; 24 tag2=0; 25 } 26 }; 27 28 const int maxn=100001; 29 30 int cnt,n,m; 31 ll mod; 32 segment tre[maxn<<2]; 33 int data[maxn]; 34 35 inline void push_up(int x){ 36 tre[x].sum=(tre[x<<1].sum+tre[x<<1|1].sum)%mod; 37 } 38 39 void build(int x,int l,int r){ 40 tre[x].l=l; tre[x].r=r; 41 if(l==r){ 42 tre[x].sum=data[l]; 43 return; 44 } 45 int mid=(l+r)>>1; 46 build(x<<1,l,mid); build(x<<1|1,mid+1,r); 47 push_up(x); 48 } 49 50 void init(){ 51 n=read(); m=read(); mod=read(); 52 for(int i=1;i<=n;i++) data[i]=read(); 53 build(1,1,n); 54 } 55 56 inline void push_down(int x){ 57 int lson=x<<1,rson=lson|1; 58 59 if(tre[x].tag1!=1){ 60 tre[lson].tag1=(tre[lson].tag1*tre[x].tag1)%mod; 61 tre[rson].tag1=(tre[rson].tag1*tre[x].tag1)%mod; 62 tre[lson].tag2=(tre[lson].tag2*tre[x].tag1)%mod; 63 tre[rson].tag2=(tre[rson].tag2*tre[x].tag1)%mod; 64 tre[lson].sum=(tre[lson].sum*tre[x].tag1)%mod; 65 tre[rson].sum=(tre[rson].sum*tre[x].tag1)%mod; 66 tre[x].tag1=1; 67 } 68 69 if(tre[x].tag2){ 70 tre[lson].tag2=(tre[lson].tag2+tre[x].tag2)%mod; 71 tre[lson].sum=(tre[lson].sum+tre[x].tag2*(tre[lson].r-tre[lson].l+1))%mod; 72 tre[rson].tag2=(tre[rson].tag2+tre[x].tag2)%mod; 73 tre[rson].sum=(tre[rson].sum+tre[x].tag2*(tre[rson].r-tre[rson].l+1))%mod; 74 tre[x].tag2=0; 75 } 76 } 77 78 void update_add(int x,int L,int R,int c){ 79 if(L<=tre[x].l&&tre[x].r<=R){ 80 tre[x].tag2=(tre[x].tag2+c)%mod; 81 tre[x].sum=(tre[x].sum+c*(tre[x].r-tre[x].l+1))%mod; 82 return; 83 } 84 85 int mid=(tre[x].l+tre[x].r)>>1; 86 if(tre[x].tag1!=1||tre[x].tag2) push_down(x); 87 if(R<=mid) update_add(x<<1,L,R,c); 88 else if(L>mid) update_add(x<<1|1,L,R,c); 89 else{ update_add(x<<1,L,mid,c); update_add(x<<1|1,mid+1,R,c); } 90 push_up(x); 91 } 92 93 void update_mul(int x,int L,int R,int c){ 94 if(L<=tre[x].l&&tre[x].r<=R){ 95 tre[x].tag1=(tre[x].tag1*c)%mod; 96 tre[x].tag2=(tre[x].tag2*c)%mod; 97 tre[x].sum=(tre[x].sum*c)%mod; 98 return; 99 } 100 101 int mid=(tre[x].l+tre[x].r)>>1; 102 if(tre[x].tag1!=1||tre[x].tag2) push_down(x); 103 if(R<=mid) update_mul(x<<1,L,R,c); 104 else if(L>mid) update_mul(x<<1|1,L,R,c); 105 else{ update_mul(x<<1,L,mid,c); update_mul(x<<1|1,mid+1,R,c); } 106 push_up(x); 107 } 108 109 ll query_sum(int x,int L,int R){ 110 if(L<=tre[x].l&&tre[x].r<=R){ 111 return tre[x].sum; 112 } 113 if(tre[x].tag1!=1||tre[x].tag2) push_down(x); 114 int mid=(tre[x].l+tre[x].r)>>1; 115 if(R<=mid) return query_sum(x<<1,L,R); 116 if(L>mid) return query_sum(x<<1|1,L,R); 117 return (query_sum(x<<1,L,mid)+query_sum(x<<1|1,mid+1,R))%mod; 118 } 119 120 void solve(){ 121 int opt,L,R,c; 122 for(int i=0;i<m;i++){ 123 opt=read(); 124 switch(opt){ 125 case 1:{ 126 L=read(); R=read(); c=read(); 127 update_mul(1,L,R,c); 128 break; 129 } 130 case 2:{ 131 L=read(); R=read(); c=read(); 132 update_add(1,L,R,c); 133 break; 134 } 135 case 3:{ 136 L=read(); R=read(); 137 printf("%lld\n",query_sum(1,L,R)); 138 break; 139 } 140 } 141 } 142 } 143 144 int main(){ 145 //freopen("temp.in","r",stdin); 146 init(); 147 solve(); 148 return 0; 149 }
她的话不多但笑起来是那么平静优雅
她柔弱的眼神里装的是什么 是思念的忧伤
以上是关于luogu P3373 模板线段树 2的主要内容,如果未能解决你的问题,请参考以下文章