原创洛谷 LUOGU P3373 模板线段树2

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原创洛谷 LUOGU P3373 模板线段树2相关的知识,希望对你有一定的参考价值。

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)

 
乘法的优先级永远比加法高。
代码如下:
  1 // LUOGU 3373 【模板】线段树2 
  2 // 2017.7.20 20:52
  3 #include<bits/stdc++.h>
  4 #define INF 0x3fffffff
  5 #define MAXN 100000
  6 #define MAXT MAXN*4
  7 using namespace std;
  8 typedef long long ll;
  9 int N,M,topt=0;
 10 ll P,a[MAXN+2];
 11 struct sgt_node{
 12     int lc,rc;
 13     ll sum,pls,mul;
 14     sgt_node(){pls=0,mul=INF;}
 15 }sgt[MAXT+2];
 16 int getint(){
 17     char ch=*;
 18     while(!isdigit(ch=getchar()));
 19     int num=ch-0;
 20     while(isdigit(ch=getchar()))num=num*10+ch-0;
 21     return num;
 22 }
 23 ll getll(){
 24     char ch=*;
 25     while(!isdigit(ch=getchar()));
 26     ll num=ch-0;
 27     while(isdigit(ch=getchar()))num=num*10+ch-0;
 28     return num;
 29 }
 30 #define lch sgt[now].lc
 31 #define rch sgt[now].rc
 32 #define smid ((l+r)>>1)
 33 void update(int now){
 34     sgt[now].sum=(sgt[lch].sum+sgt[rch].sum)%P;
 35 }
 36 void set_mul(int now,ll v){
 37     sgt[now].sum=(sgt[now].sum*v)%P;
 38     if(sgt[now].mul==INF)sgt[now].mul=v%P;
 39     else sgt[now].mul=(sgt[now].mul*v)%P;  // 必须为乘法!!!
 40     sgt[now].pls=(sgt[now].pls*v)%P;
 41 }
 42 void set_pls(int now,int l,int r,ll v){
 43     sgt[now].sum=(sgt[now].sum+v*(r-l+1))%P;
 44     sgt[now].pls=(sgt[now].pls+v)%P;
 45 }
 46 void push_down(int now,int l,int r){
 47     if(sgt[now].mul!=INF){
 48         set_mul(lch,sgt[now].mul);
 49         set_mul(rch,sgt[now].mul);
 50         sgt[now].mul=INF;
 51     }
 52     if(sgt[now].pls){
 53         set_pls(lch,l,smid,sgt[now].pls);
 54         set_pls(rch,smid+1,r,sgt[now].pls);
 55         sgt[now].pls=0;
 56     }
 57 }
 58 void Build_sgt(int &now,int l,int r){
 59     now=++topt;
 60     if(l==r){
 61         sgt[now].sum=a[l];
 62         return;
 63     }
 64     Build_sgt(lch,l,smid);
 65     Build_sgt(rch,smid+1,r);
 66     update(now);
 67 }
 68 ll Query_sgt(int now,int l,int r,int qx,int qy){
 69     if(l==qx&&r==qy)return sgt[now].sum;
 70     push_down(now,l,r);
 71     if(qy<=smid)return Query_sgt(lch,l,smid,qx,qy);
 72     if(qx>smid)return Query_sgt(rch,smid+1,r,qx,qy);
 73     return Query_sgt(lch,l,smid,qx,smid)+Query_sgt(rch,smid+1,r,smid+1,qy);
 74 }
 75 void Region_mul(int now,int l,int r,int x,int y,ll v){
 76     if(l==x&&r==y){
 77         set_mul(now,v);
 78         return;
 79     }
 80     push_down(now,l,r);
 81     if(y<=smid)Region_mul(lch,l,smid,x,y,v);
 82     else if(x>smid)Region_mul(rch,smid+1,r,x,y,v);
 83     else{
 84         Region_mul(lch,l,smid,x,smid,v);
 85         Region_mul(rch,smid+1,r,smid+1,y,v);
 86     }
 87     update(now);
 88 }
 89 void Region_pls(int now,int l,int r,int x,int y,ll v){
 90     if(l==x&&r==y){
 91         set_pls(now,l,r,v);
 92         return;
 93     }
 94     push_down(now,l,r);
 95     if(y<=smid)Region_pls(lch,l,smid,x,y,v);
 96     else if(x>smid)Region_pls(rch,smid+1,r,x,y,v);
 97     else{
 98         Region_pls(lch,l,smid,x,smid,v);
 99         Region_pls(rch,smid+1,r,smid+1,y,v);
100     }
101     update(now);
102 }
103 int main(){
104     N=getint(),M=getint(),P=getll();
105     for(int i=1;i<=N;i++)
106         a[i]=getll();
107     int root=0;
108     Build_sgt(root,1,N);
109     int op,x,y;
110     ll k;
111     for(int i=1;i<=M;i++){
112         op=getint();
113         switch(op){
114             case 1:
115                 x=getint(),y=getint(),k=getll();
116                 Region_mul(1,1,N,x,y,k);
117                 break;
118             case 2:
119                 x=getint(),y=getint(),k=getll();
120                 Region_pls(1,1,N,x,y,k);
121                 break;
122             case 3:
123                 x=getint(),y=getint();
124                 printf("%lld\n",Query_sgt(1,1,N,x,y)%P);
125                 break;
126         }
127     }    
128     return 0;
129 }

 

以上是关于原创洛谷 LUOGU P3373 模板线段树2的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P3373 模板线段树 2

luogu P3373 线段树2 模板

Luogu P3373 模板线段树 2

luogu P3373 模板线段树 2

洛谷P3373 模板线段树 2

luogu P3373 模板线段树 2