zoukankan      html  css  js  c++  java
  • 【bzoj1180】[CROATIAN2009]OTOCI LCT

    题目描述

    给出n个结点以及每个点初始时对应的权值wi。起始时点与点之间没有连边。有3类操作: 1、bridge A B:询问结点A与结点B是否连通。如果是则输出“no”。否则输出“yes”,并且在结点A和结点B之间连一条无向边。 2、penguins A X:将结点A对应的权值wA修改为X。 3、excursion A B:如果结点A和结点B不连通,则输出“impossible”。否则输出结点A到结点B的路径上的点对应的权值的和。给出q个操作,要求在线处理所有操作。数据范围:1<=n<=30000, 1<=q<=300000, 0<=wi<=1000。

    输入

    第一行包含一个整数n(1<=n<=30000),表示节点的数目。第二行包含n个整数,第i个整数表示第i个节点初始时对应的权值。第三行包含一个整数q(1<=n<=300000),表示操作的数目。以下q行,每行包含一个操作,操作的类别见题目描述。任意时刻每个节点对应的权值都是1到1000的整数。

    输出

    输出所有bridge操作和excursion操作对应的输出,每个一行。

    样例输入

    5
    4 2 4 5 6
    10
    excursion 1 1
    excursion 1 2
    bridge 1 2
    excursion 1 2
    bridge 3 4
    bridge 3 5
    excursion 4 5
    bridge 1 3
    excursion 2 4
    excursion 2 5

    样例输出

    4
    impossible
    yes
    6
    yes
    yes
    15
    yes
    15
    16


    题解

    LCT,没有删边操作

    坑点在于bridge操作时连通输出no,不连通输出yes(估计是翻译问题)

    #include <cstdio>
    #include <algorithm>
    #define N 30010
    #define lson c[0][x]
    #define rson c[1][x]
    using namespace std;
    int fa[N] , c[2][N] , w[N] , sum[N] , rev[N];
    char str[15];
    void pushup(int x)
    {
    	sum[x] = sum[lson] + sum[rson] + w[x];
    }
    void pushdown(int x)
    {
    	if(rev[x])
    	{
    		swap(c[0][lson] , c[1][lson]);
    		swap(c[0][rson] , c[1][rson]);
    		rev[lson] ^= 1 , rev[rson] ^= 1;
    		rev[x] = 0;
    	}
    }
    bool isroot(int x)
    {
    	return c[0][fa[x]] != x && c[1][fa[x]] != x;
    }
    void update(int x)
    {
    	if(!isroot(x)) update(fa[x]);
    	pushdown(x);
    }
    void rotate(int x)
    {
    	int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1;
    	if(!isroot(y)) c[c[1][z] == y][z] = x;
    	fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;
    	pushup(y) , pushup(x);
    }
    void splay(int x)
    {
    	update(x);
    	while(!isroot(x))
    	{
    		int y = fa[x] , z = fa[y];
    		if(!isroot(y))
    		{
    			if((c[0][y] == x) ^ (c[0][z] == y)) rotate(x);
    			else rotate(y);
    		}
    		rotate(x);
    	}
    }
    void access(int x)
    {
    	int t = 0;
    	while(x) splay(x) , rson = t , pushup(x) , t = x , x = fa[x];
    }
    void makeroot(int x)
    {
    	access(x) , splay(x);
    	swap(lson , rson) , rev[x] ^= 1;
    }
    int find(int x)
    {
    	access(x) , splay(x);
    	while(lson) pushdown(x) , x = lson;
    	return x;
    }
    void link(int x , int y)
    {
    	makeroot(x) , fa[x] = y;
    }
    void split(int x , int y)
    {
    	makeroot(y) , access(x) , splay(x);
    }
    int main()
    {
    	int n , m , i , x , y;
    	scanf("%d" , &n);
    	for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &w[i]) , sum[i] = w[i];
    	scanf("%d" , &m);
    	while(m -- )
    	{
    		scanf("%s%d%d" , str , &x , &y);
    		if(str[0] == 'b')
    		{
    			if(find(x) == find(y)) printf("no
    ");
    			else printf("yes
    ") , link(x , y);
    		}
    		else if(str[0] == 'p') split(x , x) , w[x] = sum[x] = y;
    		else
    		{
    			if(find(x) == find(y)) split(x , y) , printf("%d
    " , sum[x]);
    			else printf("impossible
    ");
    		}
    	}
    	return 0;
    }

     

  • 相关阅读:
    JZOJ 3034. 【NOIP2012模拟10.17】独立集
    JZOJ 3035. 【NOIP2012模拟10.17】铁轨
    JZOJ 1259. 牛棚安排
    数位DP JZOJ 3316. 非回文数字
    JZOJ 3046. 游戏
    JZOJ 3013. 填充棋盘
    debian 安装oracle提供的java8
    java 汉字转拼音 PinYin4j
    debian ssh设置root权限登陆 Permission denied, please try again
    java并发下订单生成策略
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6795254.html
Copyright © 2011-2022 走看看