CFGym 101161I 题解
一、题目链接
http://codeforces.com/gym/101161/problem/I
二、题意
给定一棵树,一个初始的省会城市,若干个询问,0表示修改省会城市,1表示查询去省会必须经过指定点的点有几个,包括指定点自身。
三、思路
1、其实这题思路不难,先以任意一个节点为根,预处理出以每个节点为根的子树的节点个数(假设为sum。sum[i]表示以初始省会为总根,以节点i为根节点的子树的节点个数,包括节点i本身)。然后,搬迁省会后,在初始省会的基础上用lca(预处理O(N)的时间,查询只需O(logN))判断给定城市和省会的层次关系然后就OK。
2、如果指定点c是省会capital或者是省会的子节点或者两者没有继承关系,直接输出sum[c];
3、否则,如果指定点c是省会capital的父节点,这时就比较麻烦了,要求出从节点c到省会capital路径上最接近节点c的那个节点编号d,n - sum[d]就是答案。注意,基于二分搜索的lca的板子里在某些情况下可以求出节点d。但是,这是某些情况(什么意思?因为lca的板子有两个返回值,后面的这个返回值可以取得该节点,但前面这个返回值不行)。要想在百分百在O(logN)复杂度内查出这个节点,貌似还不怎么好弄。
4、那怎么办呢?这么多人AC。。。。。。。绞尽脑汁也想不到什么快速的好方法啊。。。。。。。其实,你要记住,如果看到一个题很多人过了,而你能想到的办法时间复杂度比较大或者是压根没思路,就应该尝试一发暴力。
四、源代码
#include<bits/stdc++.h> using namespace std; ; typedef struct { int to, next; } Edge; Edge tree[MAXN * ]; int head[MAXN], cnt; int n, q, cap; int sum[MAXN]; void add(int from, int to) { tree[cnt].to = to; tree[cnt].next = head[from]; head[from] = cnt++; } void init() { memset(head, -, sizeof(head)); cnt = ; } void dfs_sum(int root, int par) { sum[root] = ; int to; ; i = tree[i].next) { to = tree[i].to; if(to != par) { dfs_sum(to, root); sum[root] += sum[to]; } } } ; int parent[LOGN][MAXN]; int deep[MAXN]; void dfs_lca(int root, int par, int d) { parent[][root] = par; deep[root] = d; ; i != -; i = tree[i].next) { to = tree[i].to; if(to != par) { dfs_lca(to, root, d + ); } } } void prepare(int start) { dfs_lca(start, -, ); ; k + < LOGN; ++k) { ; v <= n; ++v) { )parent[k + ][v] = -; ][v] = parent[k][parent[k][v]]; } } } int lca(int a, int b) { if(deep[a] < deep[b])swap(a, b); ; i < LOGN; ++i) { )a = parent[i][a]; } if(a == b)return a; ; i >= ; --i) { if(parent[i][a] != parent[i][b]) { a = parent[i][a]; b = parent[i][b]; } } ][a]; } int find_anc_son(int anc, int son) { ][son] == anc)return son; ][son]); } int main() { //freopen("Iinput.txt", "r", stdin); ; scanf("%d", &T); while(T--) { init(); scanf("%d%d%d", &n, &q, &cap); ; i < n; ++i) { scanf("%d%d", &a, &b); add(a, b); add(b, a); } dfs_sum(cap, -); prepare(cap); printf("Case #%d:\n", tc++); ; i < q; ++i) { scanf("%d%d", &a, &b); )cap = b; else { int anc = lca(b, cap); if(anc == cap || (anc != b && anc != cap))printf("%d\n", sum[b]); else printf("%d\n", n - sum[find_anc_son(b, cap)]); } } } ; }
CFGym 101161I 题解的更多相关文章
- CFGym 101490J 题解
一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你n个点,代表学生所在位置,n个点,代表老师所在位置.每个学生分配一个老师.让你找出一个最小的学生 ...
- CFGym 101490E 题解
一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你一个图,n个点,m条边,一个x,从顶点1走到顶点n.假设从顶点1走到顶点n的最短路为d,x代表你 ...
- CFGym 100198G 题解
一.题目链接 http://codeforces.com/gym/100198/problem/G 二.题意 看样例就能明白,写表达式解析器. 三 .思路 一看这题目,立马就会想到“后缀表达式”,考虑 ...
- CFGym 101194L 题解
一.题目链接 http://codeforces.com/gym/101194/problem/L 二.题意 有4个队伍,要打6场比赛(刚好每两个队伍都能相互比一次),若A和B比赛有3种结果: A赢B ...
- CFGym 101194D 题解
一.题目链接 http://codeforces.com/gym/101194/problem/D 二.题意 给定一个数字n和一个数字k,一个n个整数的序列,让你在里面找尽可能多的长度为k的符合“要求 ...
- CFGym 101505I 题解
一.题目链接 http://codeforces.com/gym/101505 二.题意 这题其实主要就是题意,理解题意后,就是水题了.我想了下,主要原因就是这几点: 1.题意太过英文化,很多句子不能 ...
- CFGym 100211J 题解
一.题目 二.题意 给定一个字母表(最多也就是英文小写字母的前10个字母),一个交换表,两个字符串,判断字符串A能否通过交换表的交换方式变成字符串B. 三.思路 1.一开始,比赛时,我半模拟半记忆化地 ...
- [CF-GYM]Abu Tahun Mod problem题解
前言 这道题比较简单,但我还是想了好一会 题意简述 Abu Tahun很喜欢回文. 一个数组若是回文的,那么它从前往后读和从后往前读都是一样的,比如数组\(\left\{1\right\},\left ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
随机推荐
- maven3常用命令、java项目搭建、web项目搭建
------------------------------maven3常用命令--------------------------- 1.常用命令 1)创建一个Project mvn archety ...
- VNC Viewer连接Cent OS 时的 复制粘帖 功能
虽然 VNC Viewer 比起 vsphere Client 来, 感觉性能差一点. 但毕竟也是个选择. 找了一下 它的这个 功能. 运行一下 vncconfig & 就可以了. 实测好用. ...
- FastJson/spring boot: json输出方法二
1.引入FastJson依赖包 <!-- FastJson --> <dependency> <groupId>com.alibaba</groupId> ...
- wpf 中关于Image中样式Style的一点总结
第一种写法: (1):定义样式 <Style x:Key="imgStyle" TargetType="Image"> : <!-- Tar ...
- 返回值为 Record类型的函数 初始化 Result
function TMiTeC_Storage.GetPhysInfo(Index: integer): TDeviceInfo; begin Finalize(Result); FillChar(R ...
- Python基础学习----参数和返回值
# 函数的参数和返回值 # 4种组合方式 # 1.无参无返 # def methodone(): # 2.无参有返 def methodtwo(): a=10 return a # 3.有参无返 # ...
- Linux运维学习笔记-软硬链接知识总结
文件链接 硬链接,通过索引节点来进行链接 硬链接原理图 硬链接的创建: 直接执行命令“ln 源文件 硬链接文件”,即可完成创建硬链接. 硬链接知识小结: 1.具有相同Inode节点号的多个文件是互 ...
- 在C#中调用Java生成的jar包文件的方法
C#工程调用Java已生成的jar包步骤如下: 一.使用IKVM.NET组件 首先到IKVM官网(http://www.ikvm.net)下载组件,下载地址:https://sourceforge.n ...
- vue+webpack多个项目共用组件动态打包单个项目
原文复制:https://www.jianshu.com/p/fa19a07b1496 修改了一些东西,因为sh脚本不能再window电脑执行,所以改成了node脚本.这是基于vue-cli2.0配置 ...
- TCP和UDP Client 代码
最近学习要求做网络编程,使用从网上找了一些资料,主要是网络协议的分层等通讯,你可以查看英文版的资料:CScharp网络编程英文版 下面直接给出代码吧,我想一看应该就懂. TCP Client 代码: ...