noip 2017 模拟 D1 T3
来源:互联网 发布:java调用数组参数 编辑:程序博客网 时间:2024/05/16 01:39
题目背景
在一个叫做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 个部落
输入输出样例
5 91 22 33 44 5Q 1 4C 2 1C 4 3Q 3 1Q 1 5U 1U 2C 4 3Q 3 4
YesNoNoNo
10 101 21 33 43 51 63 71 82 95 10C 8 1Q 6 1C 2 1Q 2 10U 1C 9 2C 7 3U 3Q 6 7Q 1 10
YesNoNoYes
20 201 21 32 41 51 64 71 82 95 101 112 127 131 141 1511 164 173 1818 198 20Q 13 5C 14 1C 16 11U 1U 2C 20 8Q 7 1C 7 4Q 17 17Q 1 6C 16 11C 2 1Q 16 2U 3U 5U 6C 2 1C 6 1C 13 7C 11 1
YesYesYesYesNo
说明
对于30%的数据 1<=n,m<=6000
对于另30%的数据,保证部落之间的地理关系是一条链,且 i 与 i + 1 之间有一条道路
对于另30%的数据,1<=n,m<=100000
对于100%的数据,1<=n,m<=300000
/*************************************************** * 查询两点是否连通,相当于查询两点之间是否有断点 * 那么考虑树上差分,维护每个点到根节点的路径上,断点 * 的个数,直接按照DFS序,用树状数组维护即可 **************************************************/#include <iostream>#include <cstdio>#include <vector>using namespace std;const int maxn = 300300;const int maxm = 300300;int n, m, tot, coc, root;vector <int> G[ maxn ];struct BIT{ int s[ maxn << 1 ]; void add(int p,int v){ for(int i = p ; i <= n << 1 ; i += i & (-i) ) s[ i ] += v; } int query(int p){ int rtn = 0; for(int i = p ; i ; i -= i & (-i) ) rtn += s[ i ]; return rtn; }}dis;int dep[ maxn ], son[ maxn ], fa[ maxn ], sz[ maxn ], top[ maxn ], pin[ maxn ], pout[ maxn ];int Q[ maxm ];void dfs1(int k){ sz[ k ] = 1; for(int i = 0; i < G[ k ].size(); ++i){ int kk = G[ k ][ i ]; if( kk == fa[ k ] ) continue; fa[ kk ] = k; dep[ kk ] = dep[ k ] + 1; dfs1( kk ); if( sz[ son[ k ] ] < sz[ kk ] ) son[ k ] = kk; sz[ k ] += sz[ kk ]; }}void dfs2(int k, int t){ top[ k ] = t; pin[ k ] = ++coc; if( !son[ k ] ) return ( void ) (pout[ k ] = ++coc); dfs2( son[k] , t ); for(int i = 0; i < G[ k ].size(); ++i){ int kk = G[ k ][ i ]; if( kk == fa[ k ] || kk == son[ k ] )continue; dfs2( kk , kk ); } return ( void ) (pout[ k ] = ++coc);}int lca(int x, int y){ while( top[ x ] != top[ y ] ){ if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap(x, y); x = fa[ top[ x ] ]; }return dep[ x ] < dep[ y ] ? x : y;}struct io { char op[ 1 << 25 ] , *s; io(){ //freopen("lct.in", "r", stdin); //freopen("lct.out", "w", stdout); fread( s = op , 1 , 1 << 25 , stdin ); } int read(){ int u = 0; while( *s < 48 || *s > 57 )s++; while( *s > 47 && *s < 58 )u = ( u << 1 ) + ( u << 3 ) + *s++ - 48; return u; } char gc(){ while( *s < 'A' || *s > 'Z' )s++; return *s++ ; }}ip;#define read ip.read#define gcha ip.gcint main(){ n = read(); m = read(); for(int i = 1; i < n; ++i){ int x = read() , y = read(); G[ x ].push_back( y ); G[ y ].push_back( x ); } root = n / 2; dfs1( root ); dfs2( root , root ); for(int i = 1; i <= n; ++i){ dis.add( pin[ i ], 1 ); dis.add( pout[ i ],-1 ); } while( m-- ){ char s[5]; int p, q, l, D1, D2; s[ 0 ] = gcha(); switch( s[ 0 ] ){ case 'Q':p = read(); q = read(); l = lca( p , q ); D1 = dep[ p ] + dep[ q ] - 2 * dep[ l ]; D2 = dis.query( pin[ p ] ) + dis.query( pin[ q ] ) - 2 * dis.query( pin[ l ] ); if(D1 == D2) printf("Yes\n"); else printf("No\n"); break; case 'C':p = read(); q = read(); if(dep[ p ] < dep[ q ]) p = q; Q[ ++tot ] = p; dis.add( pin[ p ], -1 ); dis.add( pout[ p ], 1 ); break; case 'U':p = read(); p = Q[ p ]; dis.add( pin[ p ], 1 ); dis.add( pout[ p ], -1 ); break; } } return 0;}
- noip 2017 模拟 D1 T3
- noip模拟11.3 T3
- NOIP 2015 [D1 T3]斗地主
- 【NOIP 2015】 D1 T3 斗地主
- 【20160904】NOIP模拟赛T3
- NOIP模拟赛 t3 nan
- [NOIP模拟]T3:系列维护
- 【NOIP模拟】 (10.24) T3 math
- 【NOIP模拟】 (10.31) T3 纸带
- NOIP 2015 D1 T3 斗地主(特详细讲解)
- 【NOIP 模拟题】[T3] 约会(lca)
- NOIP模拟(10.19)T3 放盒子
- NOIP模拟(10.20)T3 裁剪表格
- NOIP模拟(20171023)T3 拆网线
- NOIP模拟(10.22)T3 树
- NOIP模拟(10.23)T3 拆网线
- NOIP模拟(10.24)T3 Math
- NOIP模拟(20171024)T3 数学
- 蔡洪平:中国工业的进步应该少一点任性、多一点韧性
- uva534
- 易观:手机管家份额第一 支付保护需求强烈
- 森蚁A1PLUS行车记录仪 高清拍摄、空气净化、随身摄影超能跨界
- ID创意爆发 迅雷赚钱宝二代设计图公开
- noip 2017 模拟 D1 T3
- 详解卷积神经网络(CNN)
- Codeforces Round #339 (Div. 2)-C(点到线段的最短距离)
- Selenium2Library关键字
- 手把手教你快速学会双平台真实开发GitHub App React Native技术全面掌握
- vivo X6搭超快4G大运存 让手机够快才畅快 永不卡顿
- 【英鹏会】欢迎您的加入——火热报名中
- 手机软件测试用例特点
- 发布构件至Maven中央库