【luogu3950】部落冲突--树剖
题目背景
在一个叫做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”,表示从第 ppp 个部落出发的建筑工人能否到达第 q个部落
输入输出样例
- 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
- Yes
- No
- No
- No
- 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
- Yes
- No
- No
- Yes
- 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
- Yes
- Yes
- Yes
- Yes
- No
说明/提示
对于30%的数据 1<=n,m<=6000
对于另30%的数据,保证部落之间的地理关系是一条链,且 i 与 i + 1 之间有一条道路
对于另30%的数据,1<=n,m<=100000
对于100%的数据,1<=n,m<=300000
这道题用树剖,其实就是维护区间的最大值,如果两个部落间有冲突,那么就两点间的
边权赋成一,询问时区间最大值如果为一,则说明不连通,如果冲突解除,则赋成零
注意边权化为点权
代码:
- #include<cstdio>
- #include<iostream>
- #include<cstdlib>
- #include<algorithm>
- #define N 1000000
- using namespace std;
- int son[N],fa[N],head[N],top[N],cnt,tot,tr[N],wt[N],val[N],dep[N],siz[N];
- int n,m,id[N];
- struct node{
- int to,nxt,dis;
- }e[N<<1];
- struct edge {
- int l,r;
- }a[N<<1];
- void add(int from,int to,int dis)
- {
- e[++tot]=(node){to,head[from],dis};
- head[from]=tot;
- }
- void dfs1(int x,int f)
- {
- dep[x]=dep[f]+1;
- siz[x]=1;
- fa[x]=f;
- for(int i=head[x];i;i=e[i].nxt)
- {
- int y=e[i].to;
- if(y==fa[x])continue;
- val[y]=e[i].dis;
- dfs1(y,x);
- if(siz[y]>siz[son[x]])son[x]=y;
- }
- }
- void dfs2(int x,int topf)
- {
- top[x]=topf;
- id[x]=++cnt;
- wt[cnt]=val[x];
- if(!son[x])return;
- dfs2(son[x],topf);
- for(int i=head[x];i;i=e[i].nxt)
- {
- int y=e[i].to;
- if(y==fa[x]||y==son[x])continue;
- dfs2(y,y);
- }
- }
- void update(int k){
- tr[k]=max(tr[k<<1],tr[k<<1|1]);
- }
- void build(int k,int l,int r)
- {
- if(l==r)
- {
- tr[k]=wt[l];
- return;
- }
- int mid=(l+r)>>1;
- build(k<<1,l,mid);
- build(k<<1|1,mid+1,r);
- update(k);
- }
- void change(int k,int l,int r,int x,int val)
- {
- if(l==r)
- {
- tr[k]=val;
- return;
- }
- int mid=(l+r)>>1;
- if(x<=mid)change(k<<1,l,mid,x,val);
- if(x>mid)change(k<<1|1,mid+1,r,x,val);
- update(k);
- }
- int ask(int k,int l,int r,int x,int y)
- {
- int ans=-2147483647;
- if(x<=l && y>=r)
- {
- return tr[k];
- }
- int mid=(l+r)>>1;
- if(x<=mid)ans=max(ans,ask(k<<1,l,mid,x,y));
- if(y>mid)ans=max(ans,ask(k<<1|1,mid+1,r,x,y));
- return ans;
- }
- int query_chain(int x,int y)
- {
- int ans=-214748364;
- while(top[x]!=top[y])
- {
- if(dep[top[x]]<dep[top[y]])swap(x,y);
- ans=max(ans,ask(1,1,n,id[top[x]],id[x]));
- x=fa[top[x]];
- }
- if(dep[x]<dep[y])swap(x,y);
- ans=max(ans,ask(1,1,n,id[y]+1,id[x]));////边权化为点权
- return ans;
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- for(int i=1,x,y;i<=n-1;i++)
- {
- scanf("%d%d",&x,&y);
- add(x,y,0); add(y,x,0);
- }
- dfs1(1,0);
- dfs2(1,1);
- build(1,1,n);
- char s[10]; int tt=0;
- for(int i=1;i<=m;i++)
- {
- int x,y;
- scanf("%s",s+1);
- if(s[1]=='C')
- {
- tt++;
- scanf("%d%d",&a[tt].l , &a[tt].r);
- int xx;
- if(dep[a[tt].l]<dep[a[tt].r])xx=a[tt].r;
- else xx=a[tt].l;
- change(1,1,n,id[xx],1);
- }
- if(s[1]=='U')
- {
- scanf("%d",&x);
- int xx;
- if(dep[a[x].l]<dep[a[x].r])xx=a[x].r;
- else xx=a[x].l;
- change(1,1,n,id[xx],0);
- }
- if(s[1]=='Q')
- {
- scanf("%d%d",&x,&y);
- int p=query_chain(x,y);
- if(p==1)printf("No\n");
- else printf("Yes\n");
- }
- }
- return 0;
- }
- /*
- 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
- */
【luogu3950】部落冲突--树剖的更多相关文章
- 洛谷 P3950 部落冲突 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例1 输出样例1 输入样例2 输出样例2 输入样例3 输出样例3 说明 思路 AC代码 总结 题面 题目链接 P3 ...
- luogu题解 P3950部落冲突--树链剖分
题目链接 https://www.luogu.org/problemnew/show/P3950 分析 大佬都用LCT,我太弱只会树链剖分 一个很裸的维护边权树链剖分题.按照套路,对于一条边\(< ...
- [luogu3950] 部落冲突 - Link Cut Tree
有了LCT这不就是思博题了吗 #include <bits/stdc++.h> using namespace std; const int N = 1000000; int n,m,t1 ...
- 洛谷 U14475 部落冲突 【比赛】 【树链剖分 + 线段树】
题目背景 在一个叫做Travian的世界里,生活着各个大大小小的部落.其中最为强大的是罗马.高卢和日耳曼.他们之间为了争夺资源和土地,进行了无数次的战斗.期间诞生了众多家喻户晓的英雄人物,也留下了许多 ...
- lupgu P3950 部落冲突
题目链接 luogu P3950 部落冲突 题解 树剖线段树可以 lct还行 代码 #include<cstdio> #include<algorithm> inline in ...
- P3950 部落冲突
题目背景 在一个叫做Travian的世界里,生活着各个大大小小的部落.其中最为强大的是罗马.高卢和日耳曼.他们之间为了争夺资源和土地,进行了无数次的战斗.期间诞生了众多家喻户晓的英雄人物,也留下了许多 ...
- Cogs 2856. [洛谷U14475]部落冲突
2856. [洛谷U14475]部落冲突 ★★★ 输入文件:lct.in 输出文件:lct.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 在一个叫做Travi ...
- 【61测试】【dp】【二分】【前缀和】【树剖】
不要问我为什么昨天考的今天才贴解题报告.. 第一题: 给定3个字符串,求它们的最长公共子序列. 解: 考试时知道肯定是LCS的二维再加一维,用三维,可天堂有路你不走,地狱无门你偏来...灵机一动想出来 ...
- 大师教你<部落冲突>如何切换账号
前提申请两个谷歌账号,账号一和账号二,想要切换账号,只需清除部落冲突在手机上的数据即可.详情请看下文! 1. 第一次登陆,进入游戏后 2. 没有谷歌商店的童鞋,下载谷歌安装器(一键修复)以及VPNFQ ...
随机推荐
- create-react-app中的一些功能配置
1. 根路径别名@ 1. npm run eject调出配置文件.找到webpack.config.js,搜索到,alias,在下面添加一行键值对'@':paths.appSrc, alias: { ...
- [BZOJ4755][JSOI2016]扭动的回文串(manacher+Hash)
前两种情况显然直接manacher,对于第三种,枚举回文中心,二分回文半径,哈希判断即可. #include<cstdio> #include<algorithm> #defi ...
- Luogu5401 CTS2019珍珠(生成函数+容斥原理+NTT)
显然相当于求有不超过n-2m种颜色出现奇数次的方案数.由于相当于是对各种颜色选定出现次数后有序排列,可以考虑EGF. 容易构造出EGF(ex-e-x)/2=Σx2k+1/(2k+1)!,即表示该颜色只 ...
- RabbitMQ 应用二
在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,RabbitMQ内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...
- Atcoder&CodeForces杂题11.6
Preface NOIP前突然不知道做什么,感觉思维有点江僵化,就在vjudge上随便组了6道ABC D+CF Div2 C/D做,发现比赛质量还不错,知识点涉及广,难度有梯度,码量稍小,思维较多. ...
- H5之拖拽
步骤: 1.为将要拖拽的元素设置允许拖拽,并赋予dragstart事件将其id转换成数据保存: 2.为容器添加dragover属性添加事件阻止浏览器默认事件,允许元素放置,并赋予drop事件进行元素的 ...
- shell 脚本总结
一.SHELL脚本是什么?它是必需的吗? 一个SHELL脚本就是一个文本文件,它包含一个或多个命令.系统管理员会经常需要使用多个命令来完成一项任务,此时可以添加这些所有命令在一个文本文件(SHELL脚 ...
- BLE 广播格式定义
低功耗蓝牙两类报文 : 广播报文 和 数据报文. 本文讨论广播报文数据段,不包括完整报文其他部分,比如前导,接入地址等 蓝牙设备通过广播表明自己的存在,等待被连接, 就好象一个人站在接口大喊“我要脱单 ...
- linux-修改树莓派分辨率
直接在树莓派下编辑 使用命令行来编辑配置文件 sudo nano /boot/config.txt 并在config.txt文件的最后加上以下代码即可 max_usb_current=1 hdmi_g ...
- JAVA笔记整理(一),JAVA介绍
JAVA语言的版本: J2SE(Java2 Platform Standard Edition,java平台标准版),后更名为:JAVA SE J2EE(Java 2 Platform,Enterpr ...