Marked Ancestor

Time limit 8000 ms

Memory limit 131072 kB

Problem Description

You are given a tree T that consists of N nodes. Each node is numbered from 1 to N, and node 1 is always the root node of T. Consider the following two operations on T:

M v: (Mark) Mark node v.
Q v: (Query) Print the index of the nearest marked ancestor of node v which is nearest to it. Initially, only the root node is marked.

Your job is to write a program that performs a sequence of these operations on a given tree and calculates the value that each Q operation will print. To avoid too large output file, your program is requested to print the sum of the outputs of all query operations. Note that the judges confirmed that it is possible to calculate every output of query operations in a given sequence.

Input

The input consists of multiple datasets. Each dataset has the following format:

The first line of the input contains two integers N and Q, which denotes the number of nodes in the tree T and the number of operations, respectively. These numbers meet the following conditions: 1 ≤ N ≤ 100000 and 1 ≤ Q ≤ 100000.

The following N - 1 lines describe the configuration of the tree T. Each line contains a single integer pi (i = 2, … , N), which represents the index of the parent of i-th node.

The next Q lines contain operations in order. Each operation is formatted as “M v” or “Q v”, where v is the index of a node.

The last dataset is followed by a line containing two zeros. This line is not a part of any dataset and should not be processed.

Output

For each dataset, print the sum of the outputs of all query operations in one line.

Sample Input

6 3

1

1

2

3

3

Q 5

M 3

Q 5

0 0

Output for the Sample Input

4


解题心得:

  1. 题意就是有一棵树,有两种操作,第一种是将某个点标记,第二种是询问距离某个点被标记的最进的祖先节点的编号,最后需要你打印出所有询问编号的总和。
  2. 据说这题每次回溯跑暴力都能跑出来,因为时间给了八秒嘛,其实我感觉这是考了一个并查集关于树的变形

    这样改变了树的深度,在询问答案的时候就可以O(1)得到答案,那怎么改变树的的形态呢。
  3. 其实可以将树的每个结点看成一颗新的树,每次标记的时候就可以将这个标记的节点看成根节点,形成一个子树,然后将它下面没有出现子树的部分全部合并起来。

#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e5+100; int father[maxn],n,m;
bool vis[maxn];
vector <int> ve[maxn]; void init() {
for(int i=1;i<=n;i++) {
ve[i].clear();
father[i] = 1;
vis[i] = false;
}
for(int i=2;i<=n;i++) {
int temp;
scanf("%d",&temp);
ve[temp].push_back(i);
}
vis[1] = true;
} void dfs(int x,int fa) {
if(vis[x])
return ;
father[x] = fa;
for(int i=0;i<ve[x].size();i++) {
dfs(ve[x][i],fa);
}
} void Mark(int x) {
vis[x] = true;
father[x] = x;
for(int i=0;i<ve[x].size();i++)
dfs(ve[x][i],x);
} void Solve() {
long long sum = 0;
for(int i=0;i<m;i++) {
char temp[5];
int x;
scanf("%s%d",temp,&x);
if(temp[0] == 'M')
Mark(x);
else
sum += father[x];
}
printf("%lld\n",sum);
} int main() {
while(scanf("%d%d",&n,&m) && n|m) {
init();
Solve();
}
return 0;
}

Aizu:2170-Marked Ancestor的更多相关文章

  1. Aizu 2170 Marked Ancestor

    题意:出一颗树,有两种操作:1. mark  u  标记结点u2.query  u  询问离u最近的且被标记的祖先结点是哪个让你输出所有询问的和. 思路:数据量太小,直接暴力dfs就可以了 #incl ...

  2. Aizu 2170 Marked Ancestor(并查集变形)

    寻找根节点很容易让人联想到DisjointSet,但是DisjointSet只有合并操作, 所以询问离线倒着考虑,标记会一个一个消除,这时候就变成合并了. 因为询问和查询的时间以及标记生效的时间有关, ...

  3. AOJ 2170 Marked Ancestor (基础并查集)

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=45522 给定一棵树的n个节点,每个节点标号在1到n之间,1是树的根节点,有如 ...

  4. AOJ 2170 Marked Ancestor[并查集][离线]

    题意: 给你一颗N个节点的树,节点编号1到N.1总是节点的根.现在有两种操作: M v: 标记节点v Q v: 求出离v最近的标记的相邻节点.根节点一开始就标记好了. 现在给一系列操作,求出所有Q操作 ...

  5. MySql Table错误:is marked as crashed and last (automatic?) 和 Error: Table "mysql"."innodb_table_stats" not found

    一.mysql 执行select 的时候报Table错误:is marked as crashed and last (automatic?) 解决方法如下: 找到mysql的安装目录的bin/myi ...

  6. leetcode:Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  7. LeetCode OJ:Lowest Common Ancestor of a Binary Tree(最近公共祖先)

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  8. LeetCode OJ:Lowest Common Ancestor of a Binary Search Tree(最浅的公共祖先)

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  9. Marked Ancestor [AOJ2170] [并查集]

    题意: 有一个树,有些节点染色,每次有两种操作,第一,统计该节点到离它最近的染色父亲结点的的号码(Q),第二,为某一个节点染色(M),求第一种操作和. 输入: 输入由多个数据集组成.每个数据集都有以下 ...

随机推荐

  1. Android 监听APP进入后台或切换到前台方案对比

    在我们开发的过程中,经常会遇到需要我们判断app进入后台,或者切换到前台的情况.比如我们想判断app切换到前台时,显示一个解锁界面,要求用户输入解锁密码才能继续进行操作:我们想判断app切换到后台,记 ...

  2. Selenium 元素查找

    1.尽量使用ID或者name去定位元素,如果这个元素没有ID或者Name,那么就是用它最近的父节点的ID或者Name去定位. 2.写自动化脚本不是一个人的事情,是一个团队的事情,合作能更好,更轻松得完 ...

  3. Azure进阶攻略 | 该如何唤醒你?因内核超时而沉睡的Linux虚拟机!

    周五下午,当你收拾好东西准备下班,奔赴 Happy Hour 时,突然接到开发团队的电话: 对方:伙计救命啊,我在搭建开发环境,但 Azure 上的 Linux 虚拟机无法启动! 你(心里想着:你要加 ...

  4. iptable防范ddos攻击

    Basic DoS Protection https://github.com/MPOS/php-mpos/wiki/Basic-DoS-Protection # Rule 1: Limit New ...

  5. PHP : url中出现乱码问题

    例子: 在html中,将数据传到url中 当我点击“提交回复”后,跳转页面中将显示: 我们获取这个参数: 但是由于传过来的参数是中文,url会进行自动的解析成二进制的代码,那我们后台接受到的数据是解析 ...

  6. iOS开发:小技巧积累2

    http://blog.sina.com.cn/s/articlelist_1935098904_1_1.html .获取全局的Delegate对象,这样我们可以调用这个对象里的方法和变量: [(My ...

  7. 【洛谷2605】[ZJOI2010] 基站选址(线段树维护DP)

    点此看题面 大致题意: 有\(n\)个村庄,每个村庄有\(4\)个属性:\(D_i\)表示与村庄\(1\)的距离,\(C_i\)表示建立基站的费用,\(S_i\)表示能将其覆盖的建基站范围,\(W_i ...

  8. HDU(1698),线段树区间更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 区间更新重点在于懒惰标记. 当你更新的区间就是整个区间的时候,直接sum[rt] = c*(r- ...

  9. 2017.11.22 mysql数据库实现关联表更新sql语句

    比如有两张表,其中一张表某个字段的值要关联另一张表进行统计,就要用到mysql的update方法,并且left join另一张表进行联合查询. mysql关联表更新统计 sql语句如下: 代码如下 复 ...

  10. MAC os x 系统java开发环境搭建教程

    https://jingyan.baidu.com/article/3d69c55147a3baf0cf02d7ca.html