洛谷 U14475 部落冲突 【比赛】 【树链剖分 + 线段树】
题目背景
在一个叫做Travian的世界里,生活着各个大大小小的部落。其中最为强大的是罗马、高卢和日耳曼。他们之间为了争夺资源和土地,进行了无数次的战斗。期间诞生了众多家喻户晓的英雄人物,也留下了许多可歌可泣的动人故事。
其中,在大大小小的部落之间,会有一些道路相连,这些道路是Travian世界里的重要枢纽,简单起见,你可以把这些部落与部落之间相连的道路看作一颗树,可见每条道路对于Travian世界的重要程度。有了这些道路,建筑工人就可以通过这些道路进行友好外交啦。
然而,事情并不会像想象的那样美好,由于资源的匮乏,相邻的部落(由一条道路相连的部落)之间经常会发生大大小小的冲突事件,更有甚者,会升级为部落之间的大型战争。
为了避免误伤,每当两个相邻的部落之间发生大型战争之时,这两个部落间的道路是不允许通行的,对于一些强大的部落,甚至能与多个相邻的部落同时开战,同样的,这些战争地带的道路十分危险,是不可通行的。
天下之势,分久必合,当两个部落经历了不打不相识的苦战之后,他们可以签订停战协议(暂时停战,以后依旧可能再次开战),这样,两个部落之间的道路又会重新恢复为可通行状态,建筑工人们又可以经过此地购买最新的大本营设计图纸来强大自己的部落了。
为了简单起见,我们把各大战争事件按发起的时间顺序依次编号(最先发起的战争编号就为 1,第二次战争编号就为 2,以此类推),当两个部落停战之时,则会直接告诉你这场战争的编号,然后这场战争就载入了史册,不复存在了,当然,这并不会影响到其他战争的编号。
建筑工人十分讨厌战争,因为战争,想从一个部落到另一个部落进行友好交流的建筑工人可能就此白跑一趟。所以,在他们出发之前,都会向你问问能不能到达他们想去的部落。
题目描述
简单起见,你就是要处理下面三件事,所有的事件都是按照时间顺序给出的。
1.(QQQ
ppp
qqq)从第
ppp
个部落出发的建筑工人想知道能否到达第 qqq
个部落了,你要回答的便是(Yes/No),注意大小写
2.(CCC
ppp
qqq)第
ppp
个部落与第 qqq
个部落开战了,保证他们一定是相邻的部落,且目前处于停战(未开战)状态
3.(UUU
xxx
) 第 xxx
次发生的战争结束了,它将永远的被载入史册,不复存在(保证这个消息不会告诉你多次)
输入输出格式
输入格式:
第一行两个数 nnn
和 mmm,
nnn
代表了一共有 nnn
个部落,mmm
代表了以上三种事件发生的总数
接下来的 n−1n - 1n−1
行,每行两个数 ppp
, qqq,代表了第
ppp
个部落与第 qqq
个部落之间有一条道路相连
接下来的 mmm
行,每行表示一件事,详见题目描述
输出格式:
每行一个“YesYesYes”或者“NoNoNo”,表示从第
ppp
个部落出发的建筑工人能否到达第 qqq
个部落
输入输出样例
复制
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
复制
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
说明
对于30%的数据 1<=n,m<=6000
对于另30%的数据,保证部落之间的地理关系是一条链,且 i 与 i + 1 之间有一条道路
对于另30%的数据,1<=n,m<=100000
对于100%的数据,1<=n,m<=300000
题解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define fo(i,x,y) for (int i = (x); i <= (y); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 300005,maxm = 600005,INF = 1000000000; inline int read(){
int out = 0,flag = 1;char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = out * 10 + c - 48; c = getchar();}
return out * flag;
} int n,m; int head[maxn],nedge = 0;
struct EDGE{
int to,next;
}edge[maxm]; inline void build(int a,int b){
edge[nedge] = (EDGE){b,head[a]};
head[a] = nedge++;
edge[nedge] = (EDGE){a,head[b]};
head[b] = nedge++;
} void init(){
fill(head,head + maxn,-1);
n = read();
m = read();
for (int i = 1; i < n; i++) build(read(),read());
} int Siz[maxn],rt = 1,rmax = INF;
void dfs(int u,int f){
Siz[u] = 1;
int gmax = 1,to;
Redge(u)
if ((to = edge[k].to) != f){
dfs(to,u);
Siz[u] += Siz[to];
if (Siz[to] > gmax) gmax = Siz[to];
}
if (n - Siz[u] > gmax) gmax = n - Siz[u];
if (gmax < rmax){
rt = u;
rmax = gmax;
}
} int siz[maxn],top[maxn],fa[maxn],id[maxn],Hash[maxn],son[maxn],dep[maxn];
int cnt = 0; void dfs1(int u,int f,int d){
siz[u] = 1; fa[u] = f; dep[u] = ++d;
int to;
Redge(u){
if ((to = edge[k].to) != f){
dfs1(to,u,d);
siz[u] += siz[to];
if (!son[u] || siz[to] > siz[son[u]]) son[u] = to;
}
}
} void dfs2(int u,bool flag){
id[u] = ++cnt; Hash[cnt] = u;
top[u] = flag ? top[fa[u]] : u;
if (son[u]) dfs2(son[u],true);
int to;
Redge(u)
if ((to = edge[k].to) != fa[u] && to != son[u])
dfs2(to,false);
} int L,R,sum[4 * maxn]; void change(int u,int l,int r,int v){
if (l >= L && r <= R) sum[u] = v;
else {
int mid = (l + r) >> 1;
if (mid >= L) change(u<<1,l,mid,v);
else change(u<<1|1,mid + 1,r,v);
sum[u] = sum[u << 1] + sum[u << 1 | 1];
}
} int Query(int u,int l,int r){
if (l >= L && r <= R) return sum[u];
else {
int mid = l + r >> 1;
if (mid >= R) return Query(u<<1,l,mid);
else if (mid < L) return Query(u<<1|1,mid + 1,r);
else return Query(u<<1,l,mid) + Query(u<<1|1,mid + 1,r);
}
} void cal1(){
int u = read(),v = read(),ans = 0;
while (top[u] != top[v]){
if (dep[top[u]] < dep[top[v]]) swap(u,v);
L = id[top[u]]; R = id[u];
ans += Query(1,1,n);
u = fa[top[u]];
}
if (dep[u] > dep[v]) swap(u,v);
L = id[u] + 1; R = id[v];
if (L <= R) ans += Query(1,1,n);
if (ans > 0) printf("No\n");
else printf("Yes\n");
} int N = 0,U[maxn]; void cal2(int p){
if (p > 0){
int u = read(),v = read();
if (fa[v] == u) swap(u,v);
U[++N] = u;
L = R = id[u];
change(1,1,n,p);
}
else {
int x = read();
L = R = id[U[x]];
change(1,1,n,p);
}
} void solve(){
char c;
while (m--){
c = getchar();
while (c != 'Q' && c != 'C' && c != 'U') c = getchar();
if (c == 'Q'){
cal1();
}else if (c == 'C'){
cal2(1);
}else {
cal2(0);
}
//L = 1; R = n; cout<<"1 to n : "<<Query(1,1,n)<<endl;
}
} int main()
{
init();
dfs(1,0);//cout<<rt<<endl;
dfs1(rt,0,0);
dfs2(rt,0);//REP(i,n) cout<<id[i]<<endl;
solve();
return 0;
}
洛谷 U14475 部落冲突 【比赛】 【树链剖分 + 线段树】的更多相关文章
- Cogs 2856. [洛谷U14475]部落冲突
2856. [洛谷U14475]部落冲突 ★★★ 输入文件:lct.in 输出文件:lct.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 在一个叫做Travi ...
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
随机推荐
- 【MYSQL命令】查看日志是否开启及日志过期天数
show variables like 'log_%';show variables like '%expire_logs_days%'
- Delphi 实现照片抽奖-原创
有单位年会要用照片抽奖,上网搜了几个都不满意,且居然还要收费.自己写一个算了.只是有一点不爽,Delphi 7 在 Windows 7 64位下有问题,不能双击 dpr 文件直接打开项目! 关于性能: ...
- Hyperledger Fabric 1.1 -- Policy 构成
Policy 规则设计 本文主要是讲解一下在fabric中Policy的规则和写法,让大家有一个初步的认识,本文是基于fabric 1.1版本 Policy Type Policy Type 目前包括 ...
- 下载android sdk更新包离线安装解决方案
本文转载自:http://xljboox.blog.163.com/blog/static/7628448320111159354738/ 第一次安装android sdk后进行开发包的更新,你应该了 ...
- php命名空间学习笔记。
为什么要用命名空间? 在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题: 用户编写的代码 与 PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲 ...
- CSS布局之圣杯布局和双飞翼布局
其实圣杯布局和双飞翼布局实现的都是三栏布局,两边的盒子宽度固定,中间盒子自适应,也就是我们常说的固比固布局.它们实现的效果都是一样的,差别在于其实现的思想. 一.圣杯布局 html代码中,将重要的内容 ...
- PSP1130
PSP时间图: 类型 任务 开始时间 结束时间 净时间 中断时间 日期 开会 开会 16:17 16:50 33 0 20171027 开会 开会 17:00 17:22 22 0 20171028 ...
- 自我介绍for软件工程课程
石家庄铁道大学学生,正在学习软件工程课程. 对于软件工程课程,没什么太大的希望.度了一下,发现软件工程课程近年来比较脱节,这次用新课本不知道效果怎么样.嗯,等课本到手看看再说吧. 自己的目标:我希望能 ...
- 人生苦短,我用Python!
一.程序分析 1.读取文件到缓冲区 def process_file(): # 读文件到缓冲区 try: # 打开文件 f = open("C:\\Users\\panbo\\Desktop ...
- php opensll加解密类
<?php $pri = "-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCzJc4RrAqaH2Es02XQ91Cqp/JK0yX893 ...