您的位置:首页 > 其它

bzoj 1251 序列终结者

2015-11-16 10:38 176 查看
狂刷splay中,机房里不时爆出骂爹骂娘的声音。基本算裸题,唯一写错的地方是在find_k的时候要先release。因为子树的大小会变
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>

#define md
#define ll long long
#define inf 1000000000000000LL
#define eps 1e-8
#define N 500010
using namespace std;
bool rev
;
int fa
,ch
[2],sz
;
ll dt
,mx
,ad
;
int root,n;
inline bool dir(int x) { return ch[fa[x]][1]==x;}
void release(int x)
{
	if (rev[x])
	{
		rev[x]^=1;
		swap(ch[x][0],ch[x][1]);
		if (ch[x][0]) rev[ch[x][0]]^=1;
		if (ch[x][1]) rev[ch[x][1]]^=1;
	}
	int l=ch[x][0],r=ch[x][1];
	if (ad[x]!=0)
	{
		ll d=ad[x]; ad[x]=0;
		if (l) { dt[l]+=d; mx[l]+=d; ad[l]+=d;}
		if (r) { dt[r]+=d; mx[r]+=d; ad[r]+=d;}
	}
}
void update(int x)
{
	int l=ch[x][0],r=ch[x][1];
	sz[x]=sz[l]+sz[r]+1;
	mx[x]=max(dt[x],max(mx[l],mx[r]));
}
void rotate(int x)
{
	int y=fa[x],z=fa[y],b=dir(x),c=dir(y),a=ch[x][!b];
	if (z) ch[z][c]=x; else root=x;
	if (a) fa[a]=y; fa[y]=x; fa[x]=z;
	ch[x][!b]=y; ch[y][b]=a;
	update(y); update(x);
}
void splay(int x,int i)
{
	while (fa[x]!=i)
	{
		int y=fa[x],z=fa[y];
		if (z==i) { release(y); release(x); rotate(x);}
		  else
		  {
		  	release(z); release(y); release(x);
		    if (dir(x)==dir(y)) { rotate(y); rotate(x); }
		     else { rotate(x); rotate(x); }
		 }
	}
}
int find_k(int x,int k)
{
	release(x);
	if (sz[ch[x][0]]==k) return x;
	if (sz[ch[x][0]]>k) return find_k(ch[x][0],k);
	return find_k(ch[x][1],k-sz[ch[x][0]]-1);
}
int find_min(int x)
{
	while (ch[x][0]) x=ch[x][0];
	return x;
}
int build(int l,int r,int father)
{
	if (l>r) return 0;
	int mid=(l+r)>>1; fa[mid]=father;
	ch[mid][0]=build(l,mid-1,mid); ch[mid][1]=build(mid+1,r,mid);
	update(mid);
	return mid;
}
void ycl()
{
	mx[0]=dt[0]=-inf;
	root=build(1,n+2,0);
}
void outit()
{
	for (int i=1;i<=n+2;i++) printf("%d %d %d %d %d   %lld %lld %lld  %d\n",i,ch[i][0],ch[i][1],fa[i],sz[i],mx[i],dt[i],ad[i],rev[i]);
}
int main()
{
	int tt,L,R,opt; ll d;
	scanf("%d%d",&n,&tt);
	ycl(); //outit();
	while (tt--)
	{
		scanf("%d",&opt);
		if (opt==1)
		{
			scanf("%d%d%lld",&L,&R,&d);
			int x=find_k(root,L-1); splay(x,0);
			int y=find_k(root,R+1); splay(y,x);
			ad[ch[y][0]]+=d;dt[ch[y][0]]+=d;mx[ch[y][0]]+=d;
		}
		else if (opt==2)
		{
			scanf("%d%d",&L,&R);
			int x=find_k(root,L-1); splay(x,0);
			int y=find_k(root,R+1); splay(y,x);
			rev[ch[y][0]]^=1;
		}
		else
		{
			scanf("%d%d",&L,&R);
			int x=find_k(root,L-1); splay(x,0);
			int y=find_k(root,R+1); splay(y,x);
			printf("%lld\n",mx[ch[y][0]]);
		}
		//outit();
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: