BZOJ 2843: 极地旅行社 lct splay

http://www.lydsy.com/JudgeOnline/problem.php?id=2843

https://blog.csdn.net/clove_unique/article/details/50992341

和之前那道题lct求两点距离用lca不同,这道题因为给的边的两个端点是没有顺序的(没法直接按照给的点直接将某个点连到树上),所以bridge需要区间翻转的操作,因为splay维护的是链,所以区间翻转相当于将叶子变成了根,根变成叶子(链翻转过来),然后再把此时的根(x)连到y上就可以了。

penguins操作之后要access一下

excursion操作时,将x翻转为根再access y就能求出这一段上的企鹅数。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=30010;
 8 int n,m; char f[12]={};
 9 int fa[maxn]={},ch[maxn][2]={},siz[maxn]={};
10 int val[maxn]={},rev[maxn]={};
11 int sta[maxn]={},tail=0;
12 int ds[maxn]={};
13 inline void updata(int x){ siz[x] = siz[ch[x][0]] + siz[ch[x][1]]+val[x];}
14 inline bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
15 int getfa(int x){if(ds[x]==x)return x; return ds[x]=getfa(ds[x]);}
16 void rotate(int x){
17     int y=fa[x];int fy=fa[y];
18     int l=ch[y][0]==x?0:1;int r=l^1;
19     if(!isroot(y)){
20         if(ch[fy][0]==y) ch[fy][0]=x;
21         else ch[fy][1]=x;
22     }
23     fa[ch[x][r]]=y;fa[x]=fy;fa[y]=x;
24     ch[y][l]=ch[x][r];ch[x][r]=y;
25     updata(y);
26 }
27 void Swapdata(int x){
28     if(rev[x]){
29         swap(ch[x][0],ch[x][1]);
30         if(ch[x][0])rev[ch[x][0]]^=1;
31         if(ch[x][1])rev[ch[x][1]]^=1;
32         rev[x]=0;
33     }
34 }
35 void splay(int x){
36     int w=x;
37     int y,fy;sta[++tail]=x;
38     while(w&&!isroot(w)){sta[++tail]=fa[w];w=fa[w];}
39     while(tail){Swapdata(sta[tail--]);}
40     while(!isroot(x)){
41         y=fa[x];fy=fa[y];
42         if(!isroot(y)){
43             if((ch[fy][0]==y)^(ch[y][0]==x))rotate(x);
44             else rotate(y);
45         }rotate(x);
46     }updata(x);
47 }
48 void Access(int x){
49     int y=0;
50     while(x){
51         splay(x);
52         ch[x][1]=y;
53         updata(x);
54         y=x;x=fa[y];
55     }
56 }
57 void Reverse(int x){
58     Access(x);
59     splay(x);
60     rev[x]^=1;
61 }
62 void Link(int x,int y){
63     Reverse(x);fa[x]=y;
64     splay(x);
65 }
66 int main(){
67     scanf("%d",&n);
68     for(int i=1;i<=n;i++)scanf("%d",&val[i]);
69     for(int i=1;i<=n;i++)ds[i]=i;
70     scanf("%d",&m);
71     int x,y,xx,yy;
72     for(int i=1;i<=m;i++){
73         scanf("%s",f);
74         scanf("%d%d",&x,&y);
75         if(f[0]==‘b‘){
76             xx=getfa(x);yy=getfa(y);
77             if(xx==yy)printf("no\n");
78             else{
79                 printf("yes\n");ds[xx]=yy;
80                 if(x!=y)Link(x,y);
81             }
82         }
83         else if(f[0]==‘p‘){
84             val[x]=y;Access(x);splay(x);
85         }
86         else{
87             xx=getfa(x);yy=getfa(y);
88             if(xx!=yy)printf("impossible\n");
89             else{
90                 Reverse(x);Access(y);splay(y);
91                 printf("%d\n",siz[y]);
92             }
93         }
94     }
95     return 0;
96 }

原文地址:https://www.cnblogs.com/137shoebills/p/8638623.html

时间: 2024-08-30 00:12:16

BZOJ 2843: 极地旅行社 lct splay的相关文章

BZOJ 2843: 极地旅行社( LCT )

LCT.. ------------------------------------------------------------------------ #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #define clr( x , c ) me

BZOJ 1180 CROATIAN 2009 OTOCI/2843 极地旅行社 LCT

题目大意:给出一些初始相互分离的岛,有三个操作,1.分析两点是否联通,如果不连通,在之间连一条边.2.更改一个点的权值.3.询问两点之间路径上所有点的点权和. 思路:基本算是LCT的模板题了吧,好久没写了,基本都要忘了,这是照别人代码写的... CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 30010 using

【bzoj2843】极地旅行社 LCT

题目描述 不久之前,Mirko建立了一个旅行社,名叫“极地之梦”.这家旅行社在北极附近购买了N座冰岛,并且提供观光服务.当地最受欢迎的当然是帝企鹅了,这些小家伙经常成群结队的游走在各个冰岛之间.Mirko的旅行社遭受一次重大打击,以至于观光游轮已经不划算了.旅行社将在冰岛之间建造大桥,并用观光巴士来运载游客.Mirko希望开发一个电脑程序来管理这些大桥的建造过程,以免有不可预料的错误发生.这些冰岛从1到N标号.一开始时这些岛屿没有大桥连接,并且所有岛上的帝企鹅数量都是知道的.每座岛上的企鹅数量虽

BZOJ 3091: 城市旅行 [LCT splay 期望]

3091: 城市旅行 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1454  Solved: 483[Submit][Status][Discuss] Description Input Output Sample Input 4 5 1 3 2 5 1 2 1 3 2 4 4 2 4 1 2 4 2 3 4 3 1 4 1 4 1 4 Sample Output 16/3 6/1 HINT 对于所有数据满足 1<=N<=50,000 1&l

BZOJ2843: 极地旅行社

2843: 极地旅行社 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 90  Solved: 56[Submit][Status] Description 不久之前,Mirko建立了一个旅行社,名叫“极地之梦”.这家旅行社在北极附近购买了N座冰岛,并且提供观光服务.当地最受欢迎的当然是帝企鹅了,这些小家伙经常成群结队的游走在各个冰岛之间. Mirko的旅行社遭受一次重大打击,以至于观光游轮已经不划算了.旅行社将在冰岛之间建造大桥,并用观光巴士来运

【BZOJ 2843】极地旅行社

复习一下LinkCutTree的模板. #include<cstdio> #include<cstring> #include<algorithm> #define N 30003 #define read(x) x=getint() using namespace std; struct node *null; struct node { node *ch[2], *fa; int d, sum; short rev; bool pl() {return fa->

【BZOJ2843】极地旅行社(Link-Cut Tree)

[BZOJ2843]极地旅行社(Link-Cut Tree) 题面 BZOJ 题解 \(LCT\)模板题呀 没什么好说的了.. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #includ

【BZOJ2843】极地旅行社 离线+树链剖分+树状数组

[BZOJ2843]极地旅行社 Description 不久之前,Mirko建立了一个旅行社,名叫“极地之梦”.这家旅行社在北极附近购买了N座冰岛,并且提供观光服务.当地最受欢迎的当然是帝企鹅了,这些小家伙经常成群结队的游走在各个冰岛之间.Mirko的旅行社遭受一次重大打击,以至于观光游轮已经不划算了.旅行社将在冰岛之间建造大桥,并用观光巴士来运载游客.Mirko希望开发一个电脑程序来管理这些大桥的建造过程,以免有不可预料的错误发生.这些冰岛从1到N标号.一开始时这些 岛屿没有大桥连接,并且所有

BZOJ 3779 重组病毒 LCT+线段树(维护DFS序)

原题干(由于是权限题我就直接砸出原题干了,要看题意概述的话在下面): Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病毒.实验在一个封闭的局域网内进行.局域网内有n台计算机,编号为1~n.一些计算机之间通过网线直接相连,形成树形的结构.局域网中有一台特殊的计算机,称之为核心计算机.根据一些初步的研究,研究员们拟定了一个一共m步的实验.实验开始之前,核