4551: [Tjoi2016&Heoi2016]树
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 503 Solved: 304
[ Submit][ Status][ Discuss]
Description
在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下
两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个
结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖
先)你能帮帮他吗?
Input
输入第一行两个正整数N和Q分别表示节点个数和操作次数接下来N-1行,每行两个正整数u,v(1≤u,v≤n)表示u到v
有一条有向边接下来Q行,形如“opernum”oper为“C”时表示这是一个标记操作,oper为“Q”时表示这是一个询
问操作对于每次询问操作,1 ≤ N, Q ≤ 100000。
Output
输出一个正整数,表示结果
Sample Input
5 5
1 2
1 3
2 4
2 5
Q 2
C 2
Q 2
Q 5
Q 3
1 2
1 3
2 4
2 5
Q 2
C 2
Q 2
Q 5
Q 3
Sample Output
1
2
2
1
2
2
1
HINT
新加数据9组(By HFLSyzx ),未重测--2016.8.2
Source
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 1E5 + 10;
int n,m,dfs_clock,Root,dfn[maxn],L[maxn],out[maxn],a[maxn*20],c[maxn*20];
bool Mark[maxn];
char com[10];
vector <int> v[maxn];
void dfs(int x,int from)
{
dfn[x] = ++dfs_clock;
for (int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
if (to == from) continue;
L[to] = L[x] + 1;
dfs(to,x);
}
out[x] = dfs_clock;
}
void pushdown(int o)
{
if (a[o]) {
int lc = 2*o,rc = 2*o+1;
if (!c[lc] || L[c[lc]] < L[a[o]]) c[lc] = a[o];
if (!a[lc] || L[a[lc]] < L[a[o]]) a[lc] = a[o];
if (!c[rc] || L[c[rc]] < L[a[o]]) c[rc] = a[o];
if (!a[rc] || L[a[rc]] < L[a[o]]) a[rc] = a[o];
a[o] = 0;
}
}
void Modify(int o,int l,int r,int ml,int mr,int modi)
{
pushdown(o);
if (ml <= l && r <= mr) {
if (c[o] && L[c[o]] > L[modi]) return;
c[o] = a[o] = modi; return;
}
int mid = (l + r) >> 1;
if (ml <= mid) Modify(2*o,l,mid,ml,mr,modi);
if (mr > mid) Modify(2*o+1,mid+1,r,ml,mr,modi);
}
int Query(int o,int l,int r,int pos)
{
if (l == r) return c[o];
pushdown(o);
int mid = (l + r) >> 1;
if (pos <= mid) return Query(2*o,l,mid,pos);
else return Query(2*o+1,mid+1,r,pos);
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
cin >> n >> m;
for (int i = 1; i < n; i++) {
int x,y; scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
Root = 1; L[Root] = 1; dfs(Root,0);
Mark[1] = 1; Modify(1,1,n,1,n,1);
while (m--) {
scanf("%s",com);
int x; scanf("%d",&x);
if (com[0] == 'C') {
if (Mark[x]) continue;
Modify(1,1,n,dfn[x],out[x],x);
Mark[x] = 1;
}
else printf("%d\n",Query(1,1,n,dfn[x]));
}
return 0;
}