生活随笔
收集整理的這篇文章主要介紹了
P4146 序列终结者 平衡树 + lazy维护
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
文章目錄
題意:
思路:
平衡樹裸題,直接維護倆lazylazylazy就行了。
需要注意的是,只有兒子節點存在的時候才能更新,不然更新到000號節點之后,給000號點加上了奇怪的值,在pushuppushuppushup的時候如果兒子不存在就拿000號節點更新答案了,所以需要特判以下。
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std
;
typedef long long LL
;
typedef unsigned long long ULL
;
typedef pair
<int,int> PII
;const int N
=1000010,mod
=1e9+7,INF
=0x3f3f3f3f;
const double eps
=1e-6;int n
,m
;
int root
,x
,y
,z
,tot
;
struct Node {int l
,r
;int val
,mx
,rank
,size
,lazy1
,lazy2
;
}tr
[N
];void pushup(int u
) {tr
[u
].size
=tr
[tr
[u
].l
].size
+tr
[tr
[u
].r
].size
+1;tr
[u
].mx
=tr
[u
].val
;if(tr
[u
].l
) tr
[u
].mx
=max(tr
[u
].mx
,tr
[tr
[u
].l
].mx
);if(tr
[u
].r
) tr
[u
].mx
=max(tr
[u
].mx
,tr
[tr
[u
].r
].mx
);
}void pushdown(int u
) {if(tr
[u
].lazy1
) {tr
[u
].lazy1
=0;swap(tr
[u
].l
,tr
[u
].r
);if(tr
[u
].l
) tr
[tr
[u
].l
].lazy1
^=1;if(tr
[u
].r
) tr
[tr
[u
].r
].lazy1
^=1;}if(tr
[u
].lazy2
) {int lazy
=tr
[u
].lazy2
; tr
[u
].lazy2
=0;if(tr
[u
].l
) tr
[tr
[u
].l
].lazy2
+=lazy
,tr
[tr
[u
].l
].val
+=lazy
,tr
[tr
[u
].l
].mx
+=lazy
;if(tr
[u
].r
) tr
[tr
[u
].r
].lazy2
+=lazy
,tr
[tr
[u
].r
].val
+=lazy
,tr
[tr
[u
].r
].mx
+=lazy
;}
}int newnode(int v
) {int u
=++tot
;tr
[u
].l
=tr
[u
].r
=0;tr
[u
].rank
=rand(); tr
[u
].lazy1
=tr
[u
].lazy2
=0;tr
[u
].size
=1; tr
[u
].val
=0; tr
[u
].mx
=0;return u
;
}void split(int u
,int k
,int &x
,int &y
) {if(!u
) { x
=y
=0; return; }pushdown(u
);if(k
<=tr
[tr
[u
].l
].size
) y
=u
,split(tr
[u
].l
,k
,x
,tr
[u
].l
);else x
=u
,split(tr
[u
].r
,k
-tr
[tr
[u
].l
].size
-1,tr
[u
].r
,y
);pushup(u
);
}int merge(int u
,int v
) {if(!u
||!v
) return u
+v
;if(tr
[u
].rank
<tr
[v
].rank
) {pushdown(u
);tr
[u
].r
=merge(tr
[u
].r
,v
);pushup(u
);return u
;} else {pushdown(v
);tr
[v
].l
=merge(u
,tr
[v
].l
);pushup(v
);return v
;}
}void dfs(int u
) {if(!u
) return;pushdown(u
);dfs(tr
[u
].l
);printf("%d %d\n",tr
[u
].val
,tr
[u
].mx
);dfs(tr
[u
].r
);
}int main()
{
scanf("%d%d",&n
,&m
);for(int i
=1;i
<=n
;i
++) {root
=merge(root
,newnode(0));} while(m
--) {int op
,l
,r
; scanf("%d%d%d",&op
,&l
,&r
);if(op
==1) {int v
; scanf("%d",&v
);split(root
,r
,x
,z
);split(x
,l
-1,x
,y
);tr
[y
].lazy2
+=v
; tr
[y
].val
+=v
; tr
[y
].mx
+=v
;root
=merge(merge(x
,y
),z
);} else if(op
==2) {split(root
,r
,x
,z
);split(x
,l
-1,x
,y
);tr
[y
].lazy1
^=1;root
=merge(merge(x
,y
),z
);} else {split(root
,r
,x
,z
);split(x
,l
-1,x
,y
);printf("%d\n",tr
[y
].mx
);root
=merge(merge(x
,y
),z
);}}return 0;
}
總結
以上是生活随笔為你收集整理的P4146 序列终结者 平衡树 + lazy维护的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。