一、题目链接

  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. 进入mac U盘文件夹命令

    cd /Volumes 这条命令进入到你的u盘的上层文件夹,在这个文件夹里面包含了你的u盘,比如我的u盘名为SONG 则进入u盘的命令为 cd /Volumes/SONG

  2. PythonInstaller编译EXE方法+编译过程出错方案大全

    https://www.cnblogs.com/gopythoner/p/6337543.htmlhttps://www.zhihu.com/question/22963200https://blog ...

  3. CSS的三种样式表和优先级

    1.外部样式表当样式需要应用于很多页面时,外部样式表将是理想的选择.在使用外部样式表的情况下,你可以通过改变一个文件来改变整个站点的外观.每个页面使用 <link> 标签链接到样式表. & ...

  4. hdu4549矩阵快速幂+费马小定理

    转移矩阵很容易求就是|0  1|,第一项是|0| |1  1|             |1| 然后直接矩阵快速幂,要用到费马小定理 :假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(m ...

  5. UVA-10410 Tree Reconstruction (树重建)

    题目大意:给出对一棵树的BFS遍历序列和DFS遍历序列,求出每一个节点的子节点. 题目分析:在BFS的序列中,子节点的下标一定比父节点的下标至少大1(根节点与第一个子节点除外),即pos[fa]+1& ...

  6. c#LINQ表达树

    如果你已经用过LINQ, 你应该知道函数方式,以及包含的丰富的类库, 如果你仍不了解, 那根据下面的链接去熟悉一下 the LINQ tutorial,  lambda. 表达树提供了丰富的包含参数的 ...

  7. New Concept English Two 22 58

    $课文56  比声音还快! 579. Once a year, a race is held for old cars. 旧式汽车的比赛每年举行一次. 580. A lot of cars enter ...

  8. PHP ksort() 函数

    PHP ksort() 函数 PHP Array 函数 实例 按照键名对关联数组进行升序排序: <?php $age=array("Bill"=>"60&qu ...

  9. js中的reduce()函数

    1. 首先看下语法如下 2 . 写了个demo如下 var fa = [1,2,3,4] function red(a, b) { console.log(arguments); return a + ...

  10. linux命令-定时任务at

    本文主要讲解一次性计划任务的命令at的用法! 1.相关操作命令及功能介绍: 在指定的时间执行一个任务,只能执行一次进程名为atd,首先需要确认该进程是否启动,并且配置开机自启动 ps -ef | gr ...