• bzoj 4825: [Hnoi2017]单旋【dfs序+线段树+hash】


    这个代码已经不是写丑那么简单了……脑子浆糊感觉np++分分钟想暴起打死我……就这还一遍A过了……
    先都读进来hash一下,因为是平衡树所以dfs序直接按照点值来就好
    对于每个操作:
    1:set维护已插入的值,对新加入的x找到它的前驱后继,选深度大的挂上去(画图找规律,我也不知道为什么深度较浅的一定挂不上去
    2、3:对于这个节点x的右子树,深度不变,x深度变为1,其他点深度+1
    4、5:先做2、3操作,然后在set里把这个点删掉,整棵树的深度-1
    并不是很难但是情况比较多,导致main函数奇丑无比……

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<set>
    using namespace std;
    const int N=100005;
    int n,ha[N],a[N],tot,has,m,f[N],c[N][2],root;
    set<int>st;
    typedef set<int>::iterator it;
    struct qwe
    {
    	int l,r,de;
    }t[N<<2];
    struct wen
    {
    	int o,x;
    }q[N];
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void pd(int ro)
    {
    	if(t[ro].de)
    	{
    		t[ro<<1].de+=t[ro].de;
    		t[ro<<1|1].de+=t[ro].de;
    		t[ro].de=0;
    	}
    }
    void build(int ro,int l,int r)
    {
    	t[ro].l=l,t[ro].r=r;
    	if(l==r)
    		return;
    	int mid=(l+r)>>1;
    	build(ro<<1,l,mid);
    	build(ro<<1|1,mid+1,r);
    }
    void jia(int ro,int l,int r,int w)
    {
    	if(l>r)
    		return;
    	if(t[ro].l==l&&t[ro].r==r)
    	{
    		t[ro].de+=w;
    		return;
    	}
    	pd(ro);
    	int mid=(t[ro].l+t[ro].r)>>1;
    	if(r<=mid)
    		jia(ro<<1,l,r,w);
    	else if(l>mid)
    		jia(ro<<1|1,l,r,w);
    	else
    	{
    		jia(ro<<1,l,mid,w);
    		jia(ro<<1|1,mid+1,r,w);
    	}
    }
    void update(int ro,int w,int d)
    {
    	if(t[ro].l==t[ro].r)
    	{
    		t[ro].de=d;
    		return;
    	}
    	pd(ro);
    	int mid=(t[ro].l+t[ro].r)>>1;
    	if(w<=mid)
    		update(ro<<1,w,d);
    	else if(w>mid)
    		update(ro<<1|1,w,d);
    }
    int ques(int ro,int w)
    {
    	if(t[ro].l==t[ro].r)
    		return t[ro].de;
    	pd(ro);
    	int mid=(t[ro].l+t[ro].r)>>1;
    	if(w<=mid)
    		return ques(ro<<1,w);
    	else if(w>mid)
    		return ques(ro<<1|1,w);
    }
    void add(int x,int y,int d)
    {
    	int de=ques(1,x);
    	c[x][d]=y;
    	update(1,y,de+1);
    	f[y]=x;
    	st.insert(y);
    	printf("%d
    ",de+1);
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;i++)
    	{
    		q[i].o=read();
    		if(q[i].o==1)
    			q[i].x=read(),a[++tot]=q[i].x;
    	}
    	sort(a+1,a+1+tot);
    	for(int i=1;i<=tot;i++)
    		if(i==1||a[i]!=a[i-1])
    			ha[a[i]]=++has;
    	for(int i=1;i<=n;i++)
    		if(q[i].o==1)
    			q[i].x=ha[q[i].x];
    	build(1,1,tot);
    	for(int i=1;i<=n;i++)
    	{
    		if(q[i].o==1)
    		{
    			if(st.empty())
    			{
    				update(1,q[i].x,1);
    				st.insert(q[i].x);
    				f[q[i].x]=0;
    				root=q[i].x;
    				puts("1");
    			}
    			else
    			{
    				it ne=st.lower_bound(q[i].x);
    				if(ne==st.begin())
    					add(*ne,q[i].x,0);
    				else
    				{
    					it pr=ne;
    					pr--;
    					if(ne==st.end()||ques(1,*pr)>ques(1,*ne))
    						add(*pr,q[i].x,1);
    					else
    						add(*ne,q[i].x,0);
    				}
    			}
    		}
    		else if(q[i].o==2)
    		{
    			it now=st.begin();
    			int x=*now,d=ques(1,x);
    			printf("%d
    ",d);
    			if(d==1)
    				continue;
    			jia(1,1,x-1,1);
    			jia(1,f[x],tot,1);
    			update(1,x,1);
    			int rc=c[x][1],p=f[x];
    			f[x]=0;
    			c[p][0]=rc;
    			if(rc)
    				f[rc]=p;
    			c[x][1]=root;
    			f[root]=x;
    			root=x;
    		}
    		else if(q[i].o==3)
    		{
    			it now=st.end();
    			now--;
    			int x=*now,d=ques(1,x);
    			printf("%d
    ",d);
    			if(d==1)
    				continue;
    			jia(1,1,f[x],1);
    			jia(1,x+1,tot,1);
    			update(1,x,1);
    			int lc=c[x][0],p=f[x];
    			f[x]=0;
    			c[p][1]=lc;
    			if(lc)
    				f[lc]=p;
    			c[x][0]=root;
    			f[root]=x;
    			root=x;
    		}
    		else if(q[i].o==4)
    		{
    			it now=st.begin();
    			int x=*now,d=ques(1,x);
    			st.erase(x);
    			printf("%d
    ",d);
    			if(d==1)
    			{
    				root=c[x][1];
    				f[root]=0;
    				jia(1,1,tot,-1);
    				continue;
    			}
    			jia(1,x+1,f[x]-1,-1);
    			int rc=c[x][1],p=f[x];
    			f[x]=0;
    			c[p][0]=rc;
    			if(rc)
    				f[rc]=p;
    		}
    		else
    		{
    			it now=st.end();
    			now--;
    			int x=*now,d=ques(1,x);
    			st.erase(x);
    			printf("%d
    ",d);
    			if(d==1)
    			{
    				root=c[x][0];
    				f[root]=0;
    				jia(1,1,tot,-1);
    				continue;
    			}
    			jia(1,f[x]+1,x-1,-1);
    			int lc=c[x][0],p=f[x];
    			f[x]=0;
    			c[p][1]=lc;
    			if(lc)
    				f[lc]=p;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    C++顺序性容器、关联性容器与容器适配器
    Groovy与Java集成常见的坑--转
    selenium打开chrome浏览器代码
    分组密码的工作模式--wiki
    linux下C语言多线程编程实例
    C语言多线程pthread库相关函数说明
    C语言使用pthread多线程编程(windows系统)二
    C语言使用pthread多线程编程(windows系统)一
    使用_beginThreadex创建多线程(C语言版多线程)
    浅谈C语言中的联合体
  • 原文地址:https://www.cnblogs.com/lokiii/p/8519377.html
Copyright © 2020-2023  润新知