Aizu:2170-Marked Ancestor
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
解题心得:
- 题意就是有一棵树,有两种操作,第一种是将某个点标记,第二种是询问距离某个点被标记的最进的祖先节点的编号,最后需要你打印出所有询问编号的总和。
- 据说这题每次回溯跑暴力都能跑出来,因为时间给了八秒嘛,其实我感觉这是考了一个并查集关于树的变形
这样改变了树的深度,在询问答案的时候就可以O(1)得到答案,那怎么改变树的的形态呢。
- 其实可以将树的每个结点看成一颗新的树,每次标记的时候就可以将这个标记的节点看成根节点,形成一个子树,然后将它下面没有出现子树的部分全部合并起来。
#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的更多相关文章
- Aizu 2170 Marked Ancestor
题意:出一颗树,有两种操作:1. mark u 标记结点u2.query u 询问离u最近的且被标记的祖先结点是哪个让你输出所有询问的和. 思路:数据量太小,直接暴力dfs就可以了 #incl ...
- Aizu 2170 Marked Ancestor(并查集变形)
寻找根节点很容易让人联想到DisjointSet,但是DisjointSet只有合并操作, 所以询问离线倒着考虑,标记会一个一个消除,这时候就变成合并了. 因为询问和查询的时间以及标记生效的时间有关, ...
- AOJ 2170 Marked Ancestor (基础并查集)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=45522 给定一棵树的n个节点,每个节点标号在1到n之间,1是树的根节点,有如 ...
- AOJ 2170 Marked Ancestor[并查集][离线]
题意: 给你一颗N个节点的树,节点编号1到N.1总是节点的根.现在有两种操作: M v: 标记节点v Q v: 求出离v最近的标记的相邻节点.根节点一开始就标记好了. 现在给一系列操作,求出所有Q操作 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- Marked Ancestor [AOJ2170] [并查集]
题意: 有一个树,有些节点染色,每次有两种操作,第一,统计该节点到离它最近的染色父亲结点的的号码(Q),第二,为某一个节点染色(M),求第一种操作和. 输入: 输入由多个数据集组成.每个数据集都有以下 ...
随机推荐
- 移动web基础
接触retina屏 基础知识(移动Web的基础知识)排版布局(高效的移动Web布局)开发效率终端交互优化 pixel像素基础viewport视图viewport_meta标签viewport_codi ...
- iphone 微信下浏览器中数字去除下划线
在开发iphone应用程序的时候,safari下手机号码默认是有下划线的,通过下面的方法就可以去掉: <meta name="format-detection" conten ...
- [QualityCenter]QC是什么?发展历程是怎样?
QC,即Quality Center,是一个基于Web的测试管理工具.它可以组织和管理应用程序测试流程的所有阶段,包括制定测试需求.计划测试.执行测试和跟踪缺陷.此外,通过Quality Center ...
- X-Cart-5.3.1.4 (Ubuntu 16.04)
平台: Ubuntu 类型: 虚拟机镜像 软件包: x-cart-5.3.1.4 commercial ecommerce open-source x-cart 服务优惠价: 按服务商许可协议 云服务 ...
- C#多线程Thread
在项目中经常用到线程Thread,先做个简单记录,后面再完善下,方便以后参考.本人技术有限,如有不同见解之处,欢迎博友批评指正. 执行的线程Thread分无参数的,一个参数,多个参数的.直接看代码吧. ...
- C语言中 fputs() fgets() 的使用方法
一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符数组中,函数调用的形式为: fgets(字符数组名,n,文件指针): 其中的n是一个正整数.表示从文件中读出的字符串不超过 n-1 ...
- Python输入与循环
python while循环 while 语句: 执行语句 结束条件 #应用while输出1到11 counts = 1 while True: print("counts:", ...
- 洛谷 P2814 家谱
题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. 输入输出格式 输入格式: 输入由多行组成,首先是一系列有关父子关系的描述,其中每一组 ...
- Altium_Designer-PCB的覆铜步骤
1.覆铜的意义 覆铜,就是将PCB上闲置的空间作为基准面,然后用固体铜填充,这些铜区又称为灌铜.敷铜的意义在于,减小地线阻抗,提高抗干扰能力:降低压降,提高电源效率:还有,与地线相连,减小环路 ...
- 1923. Scary Politics (timus) (dfs) search
http://acm.timus.ru/problem.aspx?space=1&num=1923 -- timus This is s problem about thd dfs and s ...