题目背景

在一个叫做Travian的世界里,生活着各个大大小小的部落。其中最为强大的是罗马、高卢和日耳曼。他们之间为了争夺资源和土地,进行了无数次的战斗。期间诞生了众多家喻户晓的英雄人物,也留下了许多可歌可泣的动人故事。

其中,在大大小小的部落之间,会有一些道路相连,这些道路是Travian世界里的重要枢纽,简单起见,你可以把这些部落与部落之间相连的道路看作一颗树,可见每条道路对于Travian世界的重要程度。有了这些道路,建筑工人就可以通过这些道路进行友好外交啦。

然而,事情并不会像想象的那样美好,由于资源的匮乏,相邻的部落(由一条道路相连的部落)之间经常会发生大大小小的冲突事件,更有甚者,会升级为部落之间的大型战争。

为了避免误伤,每当两个相邻的部落之间发生大型战争之时,这两个部落间的道路是不允许通行的,对于一些强大的部落,甚至能与多个相邻的部落同时开战,同样的,这些战争地带的道路十分危险,是不可通行的。

天下之势,分久必合,当两个部落经历了不打不相识的苦战之后,他们可以签订停战协议(暂时停战,以后依旧可能再次开战),这样,两个部落之间的道路又会重新恢复为可通行状态,建筑工人们又可以经过此地购买最新的大本营设计图纸来强大自己的部落了。

为了简单起见,我们把各大战争事件按发起的时间顺序依次编号(最先发起的战争编号就为 1,第二次战争编号就为 2,以此类推),当两个部落停战之时,则会直接告诉你这场战争的编号,然后这场战争就载入了史册,不复存在了,当然,这并不会影响到其他战争的编号。

建筑工人十分讨厌战争,因为战争,想从一个部落到另一个部落进行友好交流的建筑工人可能就此白跑一趟。所以,在他们出发之前,都会向你问问能不能到达他们想去的部落。

题目描述

简单起见,你就是要处理下面三件事,所有的事件都是按照时间顺序给出的。

  1. (\(Q \ p \ q\)) 从第 \(p\) 个部落出发的建筑工人想知道能否到达第 \(q\) 个部落了,你要回答的便是 (\(Yes/No\)),注意大小写

  2. (\(C \ p \ q\)) 第 \(p\) 个部落与第 \(q\) 个部落开战了,保证他们一定是相邻的部落,且目前处于停战(未开战)状态

  3. (\(U \ x\) ) 第 \(x\) 次发生的战争结束了,它将永远的被载入史册,不复存在(保证这个消息不会告诉你多次)

输入输出格式

输入格式:

第一行两个数 \(n\) 和 \(m\) ,\(n\) 代表了一共有 \(n\) 个部落,\(m\) 代表了以上三种事件发生的总数

接下来的 \(n - 1\) 行,每行两个数 \(p\) , \(q\) ,代表了第 \(p\) 个部落与第 \(q\) 个部落之间有一条道路相连

接下来的 \(m\) 行,每行表示一件事,详见题目描述

输出格式:

每行一个“ \(Yes\) ”或者“ \(No\) ”,表示从第 \(p\) 个部落出发的建筑工人能否到达第 \(q\) 个部落

输入输出样例

输入样例#1:

5 9

1 2

2 3

3 4

4 5

Q 1 4

C 2 1

C 4 3

Q 3 1

Q 1 5

U 1

U 2

C 4 3

Q 3 4

输出样例#1:

Yes

No

No

No

输入样例#2:

10 10

1 2

1 3

3 4

3 5

1 6

3 7

1 8

2 9

5 10

C 8 1

Q 6 1

C 2 1

Q 2 10

U 1

C 9 2

C 7 3

U 3

Q 6 7

Q 1 10

输出样例#2:

Yes

No

No

Yes

输入样例#3:

20 20

1 2

1 3

2 4

1 5

1 6

4 7

1 8

2 9

5 10

1 11

2 12

7 13

1 14

1 15

11 16

4 17

3 18

18 19

8 20

Q 13 5

C 14 1

C 16 11

U 1

U 2

C 20 8

Q 7 1

C 7 4

Q 17 17

Q 1 6

C 16 11

C 2 1

Q 16 2

U 3

U 5

U 6

C 2 1

C 6 1

C 13 7

C 11 1

输出样例#3:

Yes

Yes

Yes

Yes

No

说明

对于30%的数据 1<=n,m<=6000

对于另30%的数据,保证部落之间的地理关系是一条链,且 i 与 i + 1 之间有一条道路

对于另30%的数据,1<=n,m<=100000

对于100%的数据,1<=n,m<=300000

题解

LCT

化边为点之后,裸的维护连通性的题目

#include<bits/stdc++.h>
#define ll long long
#define db double
#define ld long double
const int MAXN=300000+10,MAXM=300000+10;
int n,m,wnt;
struct war{
int u,v;
};
war W[MAXM];
std::map<int,int> M[MAXN];
#define lc(x) ch[(x)][0]
#define rc(x) ch[(x)][1]
struct LCT{
int ch[MAXN+MAXN][2],fa[MAXN+MAXM],rev[MAXN+MAXM],stack[MAXN+MAXM],cnt;
inline void init()
{
memset(ch,0,sizeof(ch));
memset(fa,0,sizeof(fa));
memset(rev,0,sizeof(rev));
}
inline bool nroot(int x)
{
return lc(fa[x])==x||rc(fa[x])==x;
}
inline void reverse(int x)
{
std::swap(lc(x),rc(x));
rev[x]^=1;
}
inline void pushdown(int x)
{
if(rev[x])
{
if(lc(x))reverse(lc(x));
if(rc(x))reverse(rc(x));
rev[x]=0;
}
}
inline void rotate(int x)
{
int f=fa[x],p=fa[f],c=(rc(f)==x);
if(nroot(f))ch[p][rc(p)==f]=x;
fa[ch[f][c]=ch[x][c^1]]=f;
fa[ch[x][c^1]=f]=x;
fa[x]=p;
}
inline void splay(int x)
{
cnt=0;
stack[++cnt]=x;
for(register int i=x;nroot(i);i=fa[i])stack[++cnt]=fa[i];
while(cnt)pushdown(stack[cnt--]);
for(register int y=fa[x];nroot(x);rotate(x),y=fa[x])
if(nroot(y))rotate((lc(y)==x)==(lc(fa[y])==y)?y:x);
}
inline void access(int x)
{
for(register int y=0;x;x=fa[y=x])splay(x),rc(x)=y;
}
inline int findroot(int x)
{
access(x);splay(x);
while(lc(x))pushdown(x),x=lc(x);
splay(x);
return x;
}
inline void makeroot(int x)
{
access(x);splay(x);reverse(x);
}
inline void split(int x,int y)
{
makeroot(x);access(y);splay(y);
}
inline void link(int x,int y)
{
makeroot(x);
if(findroot(y)!=x)fa[x]=y;
}
inline void cut(int x,int y)
{
makeroot(x);
if(findroot(y)==x&&fa[y]==x&&!rc(y))fa[y]=lc(x)=0;
}
};
LCT T;
#undef lc
#undef rc
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char c='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
int main()
{
read(n);read(m);
T.init();
for(register int i=1;i<n;++i)
{
int u,v,sn=n+i;
read(u);read(v);
if(u>v)std::swap(u,v);
M[u][v]=i;
T.link(sn,u);T.link(sn,v);
}
while(m--)
{
char opt;
std::cin>>opt;
if(opt=='Q')
{
int u,v;
read(u);read(v);
if(T.findroot(u)==T.findroot(v))puts("Yes");
else puts("No");
}
if(opt=='C')
{
++wnt;
read(W[wnt].u);read(W[wnt].v);
if(W[wnt].u>W[wnt].v)std::swap(W[wnt].u,W[wnt].v);
int sn=n+M[W[wnt].u][W[wnt].v];
T.cut(sn,W[wnt].u);T.cut(sn,W[wnt].v);
}
if(opt=='U')
{
int id,sn;
read(id);
sn=n+M[W[id].u][W[id].v];
T.link(sn,W[id].u);T.link(sn,W[id].v);
}
}
return 0;
}

【刷题】洛谷 P3950 部落冲突的更多相关文章

  1. 洛谷 P3950 部落冲突 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例1 输出样例1 输入样例2 输出样例2 输入样例3 输出样例3 说明 思路 AC代码 总结 题面 题目链接 P3 ...

  2. 洛谷P3950 部落冲突 [LCT]

    题目传送门 部落冲突 格式难调,体面就不放了. 分析: julao们应该都看得出来就是个$LCT$板子,战争就$cut$,结束就$link$,询问就$find$.没了... 太久没打$LCT$,然后发 ...

  3. 洛谷P3950 部落冲突(LCT)

    洛谷题目传送门 最无脑LCT题解,Dalao们的各种算法都比这个好多啦... 唯一的好处就是只管码代码就好了 开战cut,停战link,询问findroot判连通性 太无脑,应该不用打注释了.常数大就 ...

  4. 洛谷:P3950 部落冲突

    原题地址:https://www.luogu.org/problemnew/show/P3950 题目简述 给定一棵树,每次给定一个操作,有如下两种: 将某条边染黑 2.询问给定的u,v两点间是否有边 ...

  5. [洛谷P3950]部落冲突

    题目大意:给你一棵树,有$3$个操作: $Q\;p\;q:$询问$p,q$是否连通 $C\;p\;q:$把$p->q$这条边割断 $U\;x:$恢复第$x$次操作二 题解:可以在割断时把这条边赋 ...

  6. [题解] 洛谷P3950 部落冲突

    传送门 拿到题目,一看 裸LCT (其实是我懒得打,splay又臭又长) 首先,这道题的意思就是删掉一些边 所以常规操作 点权转边权 之后对于战争操作,在对应的边上+1 对于和平操作,在对应的边上-1 ...

  7. Cogs 2856. [洛谷U14475]部落冲突

    2856. [洛谷U14475]部落冲突 ★★★   输入文件:lct.in   输出文件:lct.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 在一个叫做Travi ...

  8. 洛谷 U14475 部落冲突 【比赛】 【树链剖分 + 线段树】

    题目背景 在一个叫做Travian的世界里,生活着各个大大小小的部落.其中最为强大的是罗马.高卢和日耳曼.他们之间为了争夺资源和土地,进行了无数次的战斗.期间诞生了众多家喻户晓的英雄人物,也留下了许多 ...

  9. lupgu P3950 部落冲突

    题目链接 luogu P3950 部落冲突 题解 树剖线段树可以 lct还行 代码 #include<cstdio> #include<algorithm> inline in ...

随机推荐

  1. 我看微软收购GitHub

    今天是微软收购GitHub的第三天,之前很多人担心被微软收购的GitHub会步Skype,诺基亚等企业的后尘,凡此种种我觉得更多人的担心是:GitHub不再开源免费罢了. GitHub今年4月刚成立十 ...

  2. phpcmsv9广告版位调用方法

    <div class="ya"> <?php // pc:get 使用sql语句获取指定条件的广告版位! ?> {pc:get sql="SELE ...

  3. linux执行命令返回码释义

    Linux 操作系统错误代码解释 0.错误代码1-10 OS error code 0: Success 操作系统错误代码0:成功 OS error code 1: Operation not per ...

  4. 【坚持】Selenium+Python学习之从读懂代码开始 DAY5

    2018/05/22 函数作为返回值 [来源:廖雪峰的官方网站](https://www.liaoxuefeng.com/) #No.1 def lazy_sum(*args): def sum(): ...

  5. 深度学习中数据的augmentation

    为了提高模型的泛化能力,同时也为了增大数据集,我们往往需要对数据进行augmentation,在这篇博客中,将总结一下可以对数据进行的augmentation. 1.颜色数据增强,对图像亮度.饱和度. ...

  6. mac 上面安装 tree 命令

    相信很多使用过Linux的用户都用过tree命令,它可以像windows的文件管理器一样清楚明了的显示目录结构. 但是mac下默认是没有 tree命令的. 1.我们可以使用find命令模拟出tree命 ...

  7. 读取classpath配置文件的方法

    http://www.cnblogs.com/sprinng/p/5622600.html

  8. Linux读书笔记第一、二章

    第一章    Linux内核简介 1.1Unix历史 Unix特点:1.很简洁 2.所有东西都被当成文件对待 3.Unix内核和相关的系统工具软件都是用C语言编写而成 4.进程创建非常迅速 1.2追寻 ...

  9. magic mouse 2 使用,移动速度问题,安装问题

    一.安装问题 首先确保你的OSX里面没有安装USB Overdrive.prefPane这个软件,就是“瑞士军刀”.这个软件会让你的magic mouse 2 连接上Mac后,Mac无限死机重启,有时 ...

  10. Teamwork(The fifth day of the team)

    在前面几天的努力中,我们已经完成了一些自己的工作,还有的就是一些完善,因为在前段时间一直都在寻找和配置Eclipse+Android SDK,由于版本和一些网络的阻碍,总是不能如愿的很好完成,经过了一 ...