zoukankan      html  css  js  c++  java
  • BZOJ1180 [CROATIAN2009]OTOCI LCT

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ1180

    本题和BZOJ2843一样。

    BZOJ2843 极地旅行社 LCT


    题意概括

      有n座岛
      每座岛上的企鹅数量虽然会有所改变,但是始终在[0, 1000]之间。你的程序需要处理以下三种命令:
      1."bridge A B"——在A与B之间建立一座大桥(A与B是不同的岛屿)。由于经费限制,这项命令被接受,当且仅当A与B不联通。若这项命令被接受,你的程序需要输出"yes",之后会建造这座大桥。否则,你的程序需要输"no"。
      2."penguins A X"——根据可靠消息,岛屿A此时的帝企鹅数量变为X。这项命令只是用来提供信息的,你的程序不需要回应。
      3."excursion A B"——一个旅行团希望从A出发到B。若A与B连通,你的程序需要输出这个旅行团一路上所能看到的帝企鹅数量(包括起点A与终点B),若不联通,你的程序需要输出"impossible"。

    题解

      本题仍然是LCT模版题。

      bridge:先判断A和B是否联通,然后连边即可。

      penguins:直接把A搞到付诸树根,然后修改就可以了。

      excursion:先判断是否联通,然后如果不联通,那么我们走类似于cut的过程,让a成为b的左子节点且为最左子节点,那么答案就是size[a]+val[b]


    代码

    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int N=30005;
    int n,m;
    int fa[N],son[N][2],size[N],rev[N],val[N];
    bool isroot(int x){
    	return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
    }
    void pushup(int x){
    	size[x]=val[x]+size[son[x][0]]+size[son[x][1]];
    }
    void pushdown(int x){
    	if (rev[x]){
    		rev[x]=0;
    		rev[son[x][0]]^=1;
    		rev[son[x][1]]^=1;
    		swap(son[x][0],son[x][1]);
    	}
    }
    void pushadd(int x){
    	if (!isroot(x))
    		pushadd(fa[x]);
    	pushdown(x);
    }
    int wson(int x){
    	return son[fa[x]][1]==x;
    }
    void rotate(int x){
    	if (isroot(x))
    		return;
    	int y=fa[x],z=fa[y],L=wson(x),R=L^1;
    	if (!isroot(y))
    		son[z][wson(y)]=x;
    	fa[x]=z,fa[y]=x,fa[son[x][R]]=y;
    	son[y][L]=son[x][R],son[x][R]=y;
    	pushup(y);
    	pushup(x);
    }
    void splay(int x){
    	pushadd(x);
    	for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
    		if (!isroot(y))
    			rotate(wson(x)==wson(y)?y:x);
    }
    void access(int x){
    	int t=0;
    	while (x){
    		splay(x);
    		son[x][1]=t;
    		pushup(x);
    		t=x;
    		x=fa[x];
    	}
    }
    void rever(int x){
    	access(x);
    	splay(x);
    	rev[x]^=1;
    }
    void link(int x,int y){
    	rever(x);
    	fa[x]=y;
    }
    void cut(int x,int y){
    	rever(x);
    	access(y);
    	splay(y);
    	fa[x]=son[y][0]=0;
    }
    int find(int x){
    	access(x);
    	splay(x);
    	while (1){
    		pushdown(x);
    		if (son[x][0])
    			x=son[x][0];
    		else
    			break;
    	}
    	return x;
    }
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++){
    		scanf("%d",&val[i]);
    		size[i]=val[i],son[i][0]=son[i][1]=fa[i]=rev[i]=0;
    	}
    	scanf("%d",&m);
    	while (m--){
    		char op[10];
    		int a,b;
    		scanf("%s%d%d",op,&a,&b);
    		if (op[0]=='b'){
    			if (find(a)==find(b))
    				puts("no");
    			else
    				puts("yes"),link(a,b);
    		}
    		else if (op[0]=='p'){
    			rever(a);
    			val[a]=b;
    			pushup(a);
    		}
    		else {
    			if (find(a)==find(b)){
    				rever(a);
    				access(b);
    				splay(b);
    				printf("%d
    ",size[son[b][0]]+val[b]);
    			}
    			else
    				puts("impossible");
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    WSS页面定制系列(1)如何启用表单页面的编辑模式
    [转载]Customizing the Context Menu of Document Library Items
    MOSS publishing功能:创建页面到子文件夹
    CodeArt.SharePoint.CamlQuery_0.9发布(源码)
    WSS页面定制系列(2)定制单个列表的表单页面
    WSS页面定制系列(3)重写表单的保存逻辑
    MOSS字段编辑权限控制方案(3)重写表单字段呈现逻辑
    WSS(MOSS)如何修改Rich文本编辑器的宽度
    web录音的实现
    WSS 扩展文件夹的属性如何给文件夹添加扩展字段
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1180.html
Copyright © 2011-2022 走看看