http://www.elijahqi.win/archives/2938
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
直接把get 写成max官方数据竟然ac了 我也是很无语..有空给洛谷加强下数据吧..
#include<cstdio>
#include<cctype>
#define N 100010
#define lc (x<<1)
#define rc (x<<1|1)
#include<algorithm>
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if(T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}
const int out_len=1<<16;
char obuf[out_len],*oh=obuf;
inline void write_char(char c){
if (oh==obuf+out_len) fwrite(obuf,1,out_len,stdout),oh=obuf;
*oh++=c;
}
template<class T>
inline void W(T x){
static int buf[30],cnt;
if (!x) write_char('0');else{
if (x<0) write_char('-'),x=-x;
for (cnt=0;x;x/=10) buf[++cnt]=x%10+48;
while(cnt) write_char(buf[cnt--]);
}
}
inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
struct node1{
int y,next;
}data[N<<1];
struct node{
int id,tag;
}tree[N<<2];
int num,h[N],in[N],out[N],n,s[N],q,dep[N];
inline void dfs(int x,int fa){
in[x]=++num;
for (int i=h[x];i;i=data[i].next){
int y=data[i].y;if(y==fa) continue;
dep[y]=dep[x]+1;dfs(y,x);
}out[x]=num;
}
inline int get(int x,int y){return dep[x]>dep[y]?x:y;}
inline void pushdown(int x){
if (!tree[x].tag) return;static int tmp;tmp=tree[lc].id;
tree[lc].id=get(tree[lc].id,tree[x].id);if (tmp!=tree[lc].id) tree[lc].tag=tree[lc].id;
tmp=tree[rc].id;tree[rc].id=get(tree[rc].id,tree[x].id);
if (tmp!=tree[rc].id) tree[rc].tag=tree[rc].id;tree[x].tag=0;
}
inline void modify(int x,int l,int r,int l1,int r1,int v){
if (l1<=l&&r1>=r) {int tmp=tree[x].id;tree[x].id=get(tree[x].id,v);
if(tree[x].id!=tmp) tree[x].tag=v;return;}int mid=l+r>>1;pushdown(x);
if (l1<=mid) modify(lc,l,mid,l1,r1,v);
if (r1>mid) modify(rc,mid+1,r,l1,r1,v);
}
inline int query(int x,int l,int r,int p){
if(l==r) return tree[x].id;int mid=l+r>>1;pushdown(x);
if(p<=mid) return query(lc,l,mid,p);else return query(rc,mid+1,r,p);
}
int main(){
freopen("bzoj4551.in","r",stdin);
n=read();q=read();
for (int i=1;i<n;++i){
int x=read(),y=read();
data[++num].y=y;data[num].next=h[x];h[x]=num;
data[++num].y=x;data[num].next=h[y];h[y]=num;
}num=0;dfs(1,1);modify(1,1,n,in[1],out[1],1);
for (int i=1;i<=q;++i){static char ch;static int x;
ch=gc();while(ch!='Q'&&ch!='C') ch=gc();
if(ch=='Q'){
x=read();W(query(1,1,n,in[x]));write_char('\n');continue;
}x=read();modify(1,1,n,in[x],out[x],x);
}flush();
return 0;
}