bzoj1251

splay大模板题。。。调了好久。。。简直智障

#include<iostream>
#include<cstdio>
#define inf 0x7fffffff
#define Abs(x) ((x) > 0 ? (x) : (-(x)))  
#define forup(i,a,b) for(int i=(a);i<=(b);i++)  
#define fordown(i,a,b) for(int i=(a);i>=(b);i--)  
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,cnt;
int fa[50005],ch[50005][2],id[50005];
int tag[50005],val[50005],mx[50005],siz[50005];
bool rev[50005];

void pushup(int node)
{ int l=ch[node][0],r=ch[node][1];
   int k=val[node];
   siz[node]=1; 
   if(l)
   {  k=max(k,mx[l]);siz[node]+=siz[l];}
   if(r)
   {k=max(k,mx[r]);siz[node]+=siz[r];}
   mx[node]=k;
}
void pushdown(int node)
{
 if(rev[node])
   {rev[node]=0;
     swap(ch[node][1],ch[node][0]);
     rev[ch[node][1]]^=1;rev[ch[node][0]]^=1;
   }
tag[ch[node][0]]+=tag[node];tag[ch[node][1]]+=tag[node];
val[ch[node][0]]+=tag[node];val[ch[node][1]]+=tag[node];
mx[ch[node][0]]+=tag[node];mx[ch[node][1]]+=tag[node];
       tag[node]=0;
}
void build(int l,int r)
{ if(l==r)
   { siz[cnt]=1;id[cnt]=l;return;}
   
   int mid=(l+r)>>1;id[cnt]=mid;
    siz[cnt]=1;
    int last=cnt;
   if(mid>l) 
     {cnt++;ch[last][0]=cnt;fa[cnt]=last;build(l,mid-1);}
    if(mid<r)
    {cnt++;ch[last][1]=cnt;fa[cnt]=last;build(mid+1,r);}
    pushup(last);
}

int s[50005];
void rotate(int x)
{  int y=fa[x],z=fa[y],l,r;
  l=(ch[y][0]==x)?0:1;r=l^1;
   if(ch[z][0]==y) ch[z][0]=x;
   else ch[z][1]=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);
}

int splay(int root,int x)
{ int top = 0;
	for(int i = x; fa[i]!=root; i = fa[i]) s[++top] = i;
	for(int i = top; i >= 1; i--)
	 pushdown(s[i]);
	
	while(fa[x]!=root)
	{ int y=fa[x],z=fa[y];
	   if(z!=root)
	   {  if((ch[y][0]==x)^(ch[z][0]==y))   rotate(x);
	     else  rotate(y);
	   }
	   rotate(x);
	 } 
}
int find(int node,int rk)
{  pushdown(node); 
if(1+siz[ch[node][0]]==rk)  return node;
    if(1+siz[ch[node][0]]>rk)  return  find(ch[node][0],rk);
  return  find(ch[node][1],rk-1-siz[ch[node][0]]);
 }
int  shaobin(int l,int r)
{ 
int p=find(ch[0][0],l);
 splay(0,p);
 int k=find(ch[0][0],r+2);
 splay(0,k);//这句话本来没加。。后来想到自己写的是双旋啊。。。不加肯定错啊
 splay(k,p);
 return ch[p][1];
}
int main()
 {//freopen("1.in","r",stdin);  
    n=read();m=read();
    
    cnt=1;
    ch[0][0]=1;fa[1]=0;
    build(0,n+1);
    for(int i=1;i<=m;i++)
    {
		int f=read(),l,r,v;	
		switch(f)
		{int root;
		case 1:l=read();r=read();v=read();
		root=shaobin(l,r);
		tag[root]+=v;mx[root]+=v;val[root]+=v;break;
		
		case 2:l=read();r=read(); 
		root=shaobin(l,r);rev[root]^=1;break;
		
		case 3:l=read();r=read();
		int x=shaobin(l,r);int top=0;
		for(int i= x; fa[i]!=0; i = fa[i]) s[++top] = i;
	for(int i = top; i >= 1; i--)
	 pushdown(s[i]);
		printf("%d\n",mx[x]);break;
		}
    }
    return 0;
}
	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值