洛谷 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
个部落
输入输出样例
复制
- 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 ...
随机推荐
- TPO-18 C2 Possible participation in a sociology project
TPO-18 C2 Possible participation in a sociology project 第 1 段 1.listen to a conversation between a s ...
- Unity 编辑器扩展 Chapter2—Gizmos
二. 使用Gizoms绘制网格及矩阵转换使用 1. 创建Leve类,作为场景控制类: using UnityEngine; //使用namespace方便脚本管理 namespace RunAndJu ...
- Windows 下在 Python (Anaconda) 中安装 Dlib 库
0. 引言 介绍在 Windows 操作系统下,在 Python 的 Anaconda 集成环境中,安装 Dlib 库 : 对于不了解源码编译的,或者利用 cmake 方法失败的,可以尝试下此方法: ...
- 【RL系列】On-Policy与Off-Policy
强化学习大致上可分为两类,一类是Markov Decision Learning,另一类是与之相对的Model Free Learning 分为这两类是站在问题描述的角度上考虑的.同样在解决方案上存在 ...
- 第六次ScrumMeeting博客
第六次ScrumMeeting博客 本次会议于10月31日(二)22时整在3公寓725房间召开,持续15分钟. 与会人员:刘畅.辛德泰.窦鑫泽.张安澜.赵奕.方科栋. 除了汇报任务外,窦鑫泽同学还就前 ...
- Django 使用 Celery 实现异步任务
对于网站来说,给用户一个较好的体验是很重要的事情,其中最重要的指标就是网站的浏览速度.因此服务端要从各个方面对网站性能进行优化,比如可采用CDN加载一些公共静态文件,如js和css:合并css或者js ...
- Python 中的实用数据挖掘
本文是 2014 年 12 月我在布拉格经济大学做的名为‘ Python 数据科学’讲座的笔记.欢迎通过 @RadimRehurek 进行提问和评论. 本次讲座的目的是展示一些关于机器学习的高级概念. ...
- js正则表达式匹配斜杠 网址 url等
项目中有个需求,需要从url中截取ID.需要在前台用js匹配截取,所以就百度一下,发现都没有说清楚,所以这里就总结下. 正则表达式如下: var epId=0; //工厂企业ID var urlInd ...
- [codecademy]css
Great work! You've learned the basics of CSS structure and syntax. We'll continue to build on these ...
- Java中的网络编程-3
用户数据协议(UDP)是网络信息传输的另外一种形式, 基于UDP的通信不同于基于TCP的通信, 基于UDP的信息传递更快, 但是不提供可靠的保证. 使用UDP传输数据时, 用户无法知道数据能否正确地到 ...