【codevs4655】序列终结者(平衡树splay)

来源:互联网 发布:学单片机有前途吗2016 编辑:程序博客网 时间:2024/06/06 03:57

题目:

我是超链接

题解:

基本是模板题,维护区间最大值

记住build的时候update以及时刻pushdown

多update几下不会错的-------天宇哥哥

代码:

#include <cstdio>#include <iostream>#include <cstring>#define N 50000#define INF 1e9using namespace std;int ch[N+5][2],f[N+5],maxn[N+5],size[N+5],key[N+5],delta[N+5],deltafz[N+5],root,sz,a[N+5];int get(int x){return ch[f[x]][1]==x;}void updata(int x){if (x){maxn[x]=key[x];if (ch[x][0]) maxn[x]=max(maxn[x],maxn[ch[x][0]]);if (ch[x][1]) maxn[x]=max(maxn[x],maxn[ch[x][1]]);size[x]=1;if (ch[x][0]) size[x]+=size[ch[x][0]];if (ch[x][1]) size[x]+=size[ch[x][1]];} }void pushdown(int x){if (delta[x]){if (ch[x][0]) delta[ch[x][0]]+=delta[x],key[ch[x][0]]+=delta[x],maxn[ch[x][0]]+=delta[x];if (ch[x][1]) delta[ch[x][1]]+=delta[x],key[ch[x][1]]+=delta[x],maxn[ch[x][1]]+=delta[x];delta[x]=0;}if (deltafz[x]){deltafz[x]=0;swap(ch[x][1],ch[x][0]);if (ch[x][0]) deltafz[ch[x][0]]^=1;if (ch[x][1]) deltafz[ch[x][1]]^=1;}}void rotate(int x){pushdown(f[x]);pushdown(x);int old=f[x],oldf=f[old],which=get(x);ch[old][which]=ch[x][which^1]; f[ch[x][which^1]]=old;ch[x][which^1]=old; f[old]=x;f[x]=oldf;if (oldf) ch[oldf][ch[oldf][1]==old]=x;updata(old);updata(x);}void splay(int x,int tar){for (int fa;(fa=f[x])!=tar;rotate(x))  if (f[fa]!=tar) rotate(get(x)==get(fa)?fa:x);if (tar==0) root=x;}int build(int fa,int l,int r){if (l>r) return 0;int mid=(l+r)>>1;int now=++sz; size[now]=1; f[now]=fa; key[now]=maxn[now]=a[mid];int lch=build(now,l,mid-1);int rch=build(now,mid+1,r);ch[now][0]=lch; ch[now][1]=rch;updata(now);return now;}int find(int x){int now=root;while (1){pushdown(now);if (ch[now][0] && x<=size[ch[now][0]]) now=ch[now][0];else {x-=size[ch[now][0]]+1;if (!x) return now;now=ch[now][1];}}}int main(){int n,m,i;scanf("%d%d",&n,&m); a[1]=-INF; a[n+2]=INF;root=build(0,1,n+2);for (i=1;i<=m;i++){int opt,l,r,v;scanf("%d",&opt);scanf("%d%d",&l,&r);int a1=find(l),a2=find(r+2);splay(a1,0);splay(a2,a1);if (opt==1){scanf("%d",&v);delta[ch[ch[root][1]][0]]+=v;maxn[ch[ch[root][1]][0]]+=v;key[ch[ch[root][1]][0]]+=v;updata(ch[root][1]);updata(root);}else  if (opt==2)    deltafz[ch[ch[a1][1]][0]]^=1;else  printf("%d\n",maxn[ch[ch[a1][1]][0]]);}}


0 0
原创粉丝点击