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. 1.字符串池化(intern)机制及拓展学习

    1.字符串intern机制 用了这么久的python,时刻和字符串打交道,直到遇到下面的情况: a = "hello" b = "hello" print(a ...

  2. JavaScript流程语句

    循环语句 while 语法 while(条件表达式){ 循环执行代码段 } 流程 1.判断条件表达式的值 2.当值为true时,循环执行代码段 3.当值为false时退出循环体 特性 先检查条件,再执 ...

  3. python模块详解 logging

    打印日志的五个级别: import logging logging.debug('test debug') logging.info('test info') logging.warning('tes ...

  4. yum第三方源

    EPEL RHEL 6: http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm RHEL 7: http:// ...

  5. NFS笔记(一)NFS服务器工作原理及详细配置

    一.NFS工作原理 1.什么是NFS服务器 NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器.不同的操作系统可以共享彼此的文件. NFS服务器可以让P ...

  6. 如何将centos7自带的firewall防火墙更换为iptables防火墙

    用惯了centos6的iptables防火墙,对firewall太无感了,那么如何改回原来熟悉的iptables防火墙呢? 1.关闭firewall防火墙 [root@centos7 html]# s ...

  7. win10下同时安装jdk1.7,1.8

    摘要:在开发不同项目时,可能会用到不同的jdk,需要我们在不同的jdk之间切换,怎么样在同一电脑上装不同的jdk,以此总结 1.正常安装jdk1.7,1.8     显示安装了jdk1.7,再安装jd ...

  8. TP5.1:将外部资源引入到框架中(css/js/font文件)

    为了让我们的框架形式变得更加好看,我们需要加入Bootstrap和Jq文件到框架中 1.通过Bootstrap和jq官网进行相关文件的下载 (1)Bootstrap下载地址:https://v3.bo ...

  9. *1 Two Sum two pointers(hashmap one scan)

    Given an array of integers, return indices of the two numbers such that they add up to a specific ta ...

  10. selenium 打开浏览器报错java.lang.NoSuchMethodError: org.openqa.selenium.chrome.ChromeOptions.addArguments([Ljava/lang/String;)

    java.lang.NoSuchMethodError: org.openqa.selenium.chrome.ChromeOptions.addArguments([Ljava/lang/Strin ...