4551: [Tjoi2016&Heoi2016]树

来源:互联网 发布:mysql压缩版怎么安装 编辑:程序博客网 时间:2024/05/22 16:04

4551: [Tjoi2016&Heoi2016]树

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 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

Sample Output

1
2
2
1

HINT

 新加数据9组(By HFLSyzx ),未重测--2016.8.2

Source

[Submit][Status][Discuss]

用dfs序把所有点排成一排,就可以区间赋值啦
#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 DMCfreopen("DMC.txt","r",stdin);#endifcin >> 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;}

0 0
原创粉丝点击