【FHQ-Treap】P4146 序列终结者

题意:

  给定一个序列,支持区间加,区间反转,区间max询问


 

裸的平衡树题,这里采用FHQ-Treap

每个节点多记录一个max值和两个lazy_tag,暴力Push_Down即可(大常数选手)

打完这道模板题可怜的Leven就要去准备初赛了qwq

 1 #include<bits/stdc++.h>
 2 #define writeln(x)  write(x),puts("")
 3 #define writep(x)   write(x),putchar(' ')
 4 using namespace std;
 5 inline int read(){
 6     int ans=0,f=1;char chr=getchar();
 7     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
 8     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
 9     return ans*f;
10 }void write(int x){
11     if(x<0) putchar('-'),x=-x;
12     if(x>9) write(x/10);
13     putchar(x%10+'0');
14 }const int M = 1e5+5;
15 struct P{int l,r,sz,x,s,lz1,lz2,key;}s[M];
16 int n,m,a[M],root,x,y,z,cnt;
17 inline void Push_Up(int x){
18     s[x].sz=s[s[x].l].sz+s[s[x].r].sz+1;
19     s[x].s=s[x].x;
20     if(s[x].l)s[x].s=max(s[x].s,s[s[x].l].s);
21     if(s[x].r)s[x].s=max(s[x].s,s[s[x].r].s);
22 }inline void Push_Down1(int x){
23     if(!s[x].lz1)return;
24     swap(s[x].l,s[x].r);
25     s[s[x].l].lz1^=1;
26     s[s[x].r].lz1^=1;
27     s[x].lz1=0;
28 }inline void Push_Down2(int x){
29     Push_Down1(x);
30     if(!s[x].lz2)return;
31     s[s[x].l].lz2+=s[x].lz2;
32     s[s[x].l].x+=s[x].lz2;
33     s[s[x].r].lz2+=s[x].lz2;
34     s[s[x].l].s+=s[x].lz2;
35     s[s[x].r].x+=s[x].lz2;
36     s[s[x].r].s+=s[x].lz2;
37     s[x].lz2=0;
38 }inline int Merge(int x,int y){
39     if(!x||!y)return x+y;
40     Push_Down2(x),Push_Down2(y);
41     if(s[x].key<s[y].key){
42         s[x].r=Merge(s[x].r,y);
43         Push_Up(x);return x;
44     }s[y].l=Merge(x,s[y].l);
45     Push_Up(y);return y;
46 }inline void Split(int now,int sz,int &x,int &y){
47     if(!now)return x=y=0,void();
48     Push_Down2(now);
49     if(s[s[now].l].sz>=sz)y=now,Split(s[now].l,sz,x,s[now].l);
50     else x=now,Split(s[now].r,sz-s[s[now].l].sz-1,s[now].r,y);
51     Push_Up(now);
52 }inline void Add(){
53     int l=read(),r=read(),p=read();
54     Split(root,l-1,x,y),Split(y,r-l+1,y,z);
55     s[y].lz2+=p;s[y].s+=p;s[y].x+=p;
56     root=Merge(Merge(x,y),z);
57 }inline void Reverse(){
58     int l=read(),r=read();
59     Split(root,l-1,x,y),Split(y,r-l+1,y,z);
60     s[y].lz1^=1;
61     root=Merge(Merge(x,y),z);
62 }inline void Query(){
63     int l=read(),r=read();
64     Split(root,l-1,x,y),Split(y,r-l+1,y,z);
65     printf("%d\n",s[y].s);
66     root=Merge(Merge(x,y),z);
67 }inline void Insert(int val){
68     s[++cnt]=(P){0,0,1,val,val,0,0,rand()};
69     root=Merge(cnt,root);
70 }int main(){
71     srand(unsigned(time(0)));
72     n=read(),m=read();
73     for(int i=1;i<=n;i++)Insert(0);
74     while(m--){
75         int opt=read();
76         if(opt==1)Add();
77         else if(opt==2)Reverse();
78         else Query();
79     }return 0;
80 }

 

posted @ 2019-10-15 06:55  zheng_liwen  阅读(154)  评论(0编辑  收藏  举报
/*去广告*/