一、题目链接

  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 题解的更多相关文章

  1. CFGym 101490J 题解

    一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你n个点,代表学生所在位置,n个点,代表老师所在位置.每个学生分配一个老师.让你找出一个最小的学生 ...

  2. CFGym 101490E 题解

    一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你一个图,n个点,m条边,一个x,从顶点1走到顶点n.假设从顶点1走到顶点n的最短路为d,x代表你 ...

  3. CFGym 100198G 题解

    一.题目链接 http://codeforces.com/gym/100198/problem/G 二.题意 看样例就能明白,写表达式解析器. 三 .思路 一看这题目,立马就会想到“后缀表达式”,考虑 ...

  4. CFGym 101194L 题解

    一.题目链接 http://codeforces.com/gym/101194/problem/L 二.题意 有4个队伍,要打6场比赛(刚好每两个队伍都能相互比一次),若A和B比赛有3种结果: A赢B ...

  5. CFGym 101194D 题解

    一.题目链接 http://codeforces.com/gym/101194/problem/D 二.题意 给定一个数字n和一个数字k,一个n个整数的序列,让你在里面找尽可能多的长度为k的符合“要求 ...

  6. CFGym 101505I 题解

    一.题目链接 http://codeforces.com/gym/101505 二.题意 这题其实主要就是题意,理解题意后,就是水题了.我想了下,主要原因就是这几点: 1.题意太过英文化,很多句子不能 ...

  7. CFGym 100211J 题解

    一.题目 二.题意 给定一个字母表(最多也就是英文小写字母的前10个字母),一个交换表,两个字符串,判断字符串A能否通过交换表的交换方式变成字符串B. 三.思路 1.一开始,比赛时,我半模拟半记忆化地 ...

  8. [CF-GYM]Abu Tahun Mod problem题解

    前言 这道题比较简单,但我还是想了好一会 题意简述 Abu Tahun很喜欢回文. 一个数组若是回文的,那么它从前往后读和从后往前读都是一样的,比如数组\(\left\{1\right\},\left ...

  9. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

随机推荐

  1. maven3常用命令、java项目搭建、web项目搭建

    ------------------------------maven3常用命令--------------------------- 1.常用命令 1)创建一个Project mvn archety ...

  2. VNC Viewer连接Cent OS 时的 复制粘帖 功能

    虽然 VNC Viewer 比起 vsphere Client 来, 感觉性能差一点. 但毕竟也是个选择. 找了一下 它的这个 功能. 运行一下 vncconfig & 就可以了. 实测好用. ...

  3. FastJson/spring boot: json输出方法二

    1.引入FastJson依赖包 <!-- FastJson --> <dependency> <groupId>com.alibaba</groupId> ...

  4. wpf 中关于Image中样式Style的一点总结

    第一种写法: (1):定义样式 <Style x:Key="imgStyle" TargetType="Image">  : <!-- Tar ...

  5. 返回值为 Record类型的函数 初始化 Result

    function TMiTeC_Storage.GetPhysInfo(Index: integer): TDeviceInfo; begin Finalize(Result); FillChar(R ...

  6. Python基础学习----参数和返回值

    # 函数的参数和返回值 # 4种组合方式 # 1.无参无返 # def methodone(): # 2.无参有返 def methodtwo(): a=10 return a # 3.有参无返 # ...

  7. Linux运维学习笔记-软硬链接知识总结

    文件链接   硬链接,通过索引节点来进行链接 硬链接原理图 硬链接的创建: 直接执行命令“ln 源文件 硬链接文件”,即可完成创建硬链接. 硬链接知识小结: 1.具有相同Inode节点号的多个文件是互 ...

  8. 在C#中调用Java生成的jar包文件的方法

    C#工程调用Java已生成的jar包步骤如下: 一.使用IKVM.NET组件 首先到IKVM官网(http://www.ikvm.net)下载组件,下载地址:https://sourceforge.n ...

  9. vue+webpack多个项目共用组件动态打包单个项目

    原文复制:https://www.jianshu.com/p/fa19a07b1496 修改了一些东西,因为sh脚本不能再window电脑执行,所以改成了node脚本.这是基于vue-cli2.0配置 ...

  10. TCP和UDP Client 代码

    最近学习要求做网络编程,使用从网上找了一些资料,主要是网络协议的分层等通讯,你可以查看英文版的资料:CScharp网络编程英文版 下面直接给出代码吧,我想一看应该就懂. TCP Client 代码: ...