splay区间模板-1331-序列终结者1
Posted wuwendongxi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了splay区间模板-1331-序列终结者1相关的知识,希望对你有一定的参考价值。
#include <iostream>
#include <cstdio>
#include <algorithm>
#define maxn 100005
using namespace std;
int n,m;
int val[maxn],num[maxn],siz[maxn],ch[maxn][3],fa[maxn],maxx[maxn],sum[maxn],flag[maxn],cnt,root;
void pushup(int x)
{
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+num[x];
maxx[x]=val[x];
if(ch[x][0]) maxx[x]=max(maxx[x],maxx[ch[x][0]]);
if(ch[x][1]) maxx[x]=max(maxx[x],maxx[ch[x][1]]);
}
void pushdown(int x)
{
if(!x) return;
if(flag[x])
{
if(ch[x][0]){flag[ch[x][0]]^=1; swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);}
if(ch[x][1]){flag[ch[x][1]]^=1; swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);}
flag[x]=0;
}
if(sum[x])
{
if(ch[x][0]) sum[ch[x][0]]+=sum[x],val[ch[x][0]]+=sum[x],maxx[ch[x][0]]+=sum[x];
if(ch[x][1]) sum[ch[x][1]]+=sum[x],val[ch[x][1]]+=sum[x],maxx[ch[x][1]]+=sum[x];
sum[x]=0;
}
}
void table()
{
ch[1][1]=n+2; fa[n+2]=1;
val[1]=0; val[n+2]=0;
num[1]=num[n+2]=1; siz[1]=2; siz[n+2]=1;
cnt=1; root=1;
}
void rot(int x,int &f)
{
int y=fa[x],z=fa[y],l=(ch[y][0]!=x),r=(l^1);
if(y==f) f=x;
else ch[z][ch[z][1]==y]=x;
fa[x]=z; fa[y]=x; fa[ch[x][r]]=y;
ch[y][l]=ch[x][r]; ch[x][r]=y;
pushup(y); pushup(x);
}
void splay(int x,int &f)
{
while(x!=f)
{
int y=fa[x],z=fa[y];
pushdown(z); pushdown(y); pushdown(x);
if(y!=f){if(ch[z][0]==y^ch[y][0]==x) rot(x,f);else rot(y,f);}
rot(x,f);
}
}
int findk(int x,int rt)
{
if(!x)return 0;
pushdown(rt);int temp;
if(siz[ch[rt][0]]+num[rt]>=x&&siz[ch[rt][0]]<x) temp=rt;
else if(siz[ch[rt][0]]>=x) temp=findk(x,ch[rt][0]);
else temp=findk(x-siz[ch[rt][0]]-num[rt],ch[rt][1]);
pushup(rt);
return temp;
}
int main()
{
scanf("%d%d",&n,&m); table();
for(int i=1;i<=n;++i)
{
int a=findk(i,root),b=findk(i+1,root);
splay(a,root); splay(b,ch[a][1]);
ch[b][0]=++cnt; num[cnt]=siz[cnt]=1; fa[cnt]=b;
pushup(cnt); pushup(b); pushup(a);
}
cnt=n+2;
while(m--)
{
int f1,f2,f3,f4; scanf("%d",&f1);
if(f1==1)
{
scanf("%d%d%d",&f2,&f3,&f4);
int a=findk(f2,root),b=findk(f3+2,root);
splay(a,root); splay(b,ch[a][1]);
sum[ch[b][0]]+=f4; val[ch[b][0]]+=f4; maxx[ch[b][0]]+=f4;
pushup(b); pushup(a);
}
else if(f1==2)
{
scanf("%d%d",&f2,&f3);int a=findk(f2,root),b=findk(f3+2,root);
splay(a,root); splay(b,ch[a][1]);
flag[ch[b][0]]^=1;
swap(ch[ch[b][0]][0],ch[ch[b][0]][1]);
}
else if(f1==3)
{
scanf("%d%d",&f2,&f3);int a=findk(f2,root),b=findk(f3+2,root);
splay(a,root); splay(b,ch[a][1]);
printf("%d
",maxx[ch[b][0]]);
}
}
return 0;
}
以上是关于splay区间模板-1331-序列终结者1的主要内容,如果未能解决你的问题,请参考以下文章