2
大神们的博客基本是没有注释,也许是太简单了吧,可是我还是看了半天,尝试着理解了一些
做法是先把题目的树建立出来,然后DFS进行重新编号,使得老板和员工在一段连续的区间,这样就
转化成了线段树进行区间的更新,单点的查询,关键便是建立题目的树,以及遍历编号
对于很多人用的边的表示,我觉得是一种类似兄弟儿子表示法的方法(如果不对,还请指教)
#include<bits/stdc++.h> using namespace std; template<class T>inline T read(T&x) { char c; while((c=getchar())<=32)if(c==EOF)return -1; bool ok=false; if(c=='-')ok=true,c=getchar(); for(x=0; c>32; c=getchar()) x=x*10+c-'0'; if(ok)x=-x; return 1; } template<class T> inline T read_(T&x,T&y) { return read(x)!=-1&&read(y)!=-1; } template<class T> inline T read__(T&x,T&y,T&z) { return read(x)!=-1&&read(y)!=-1&&read(z)!=-1; } template<class T> inline void write(T x) { if(x<0)putchar('-'),x=-x; if(x<10)putchar(x+'0'); else write(x/10),putchar(x%10+'0'); } template<class T>inline void writeln(T x) { write(x); putchar('\n'); } //-------ZCC IO template------ const int maxn=50010; const double inf=999999999; #define lson (rt<<1),L,M #define rson (rt<<1|1),M+1,R #define M ((L+R)>>1) #define For(i,t,n) for(int i=(t);i<(n);i++) typedef long long LL; typedef double DB; #define bug printf("---\n"); struct Edge// { int to,next;//树的边的表示,to表示边的下端点,next表示以边的上端点为公共点的相邻点 }edge[maxn]; bool vis[maxn];//标记那些点做过儿子,那么没有做过儿子的就是树根 int head[maxn],start[maxn],endd[maxn];//head[i]表示以i为结点的公共边的条的号码,start[i]到end[i]表示以结点i为老板的所有员工的编号 int tot,cnt;//tot表示边数,cnt表示DFS对各点的编码 void init() { tot=cnt=0; memset(head,-1,sizeof(head)); memset(vis,false,sizeof(vis)); } void addedge(int u,int v)//以边表示数 { edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } void dfs(int u) { start[u]=++cnt;//老板的起点编号 for(int i=head[u];~i;i=edge[i].next) dfs(edge[i].to); endd[u]=cnt;//他最后的员工的编号 } struct node { int inv,val; }p[maxn<<2]; void build(int rt,int L,int R) { p[rt].val=-1; p[rt].inv=0; if(L==R)return ; build(lson); build(rson); } void update(int rt,int L,int R,int x,int y,int v) { //printf("%d %d %d %d %d %d\n",rt,L,R,x,y,v); if(L==x&&y==R) { p[rt].val=v; p[rt].inv=1; return ; } if(p[rt].inv) { p[rt<<1].inv=p[rt<<1|1].inv=1; p[rt<<1].val=p[rt<<1|1].val=p[rt].val; p[rt].inv=0; } if(y<=M) update(lson,x,y,v); else if(x>M) update(rson,x,y,v); else { update(lson,x,M,v); update(rson,M+1,y,v); } } int query(int rt,int L,int R,int i) { if(L==R) { return p[rt].val; } if(p[rt].inv) { p[rt<<1].inv=p[rt<<1|1].inv=1; p[rt<<1].val=p[rt<<1|1].val=p[rt].val; p[rt].inv=0; } if(i<=M)return query(lson,i); else return query(rson,i); } int main() { // #ifndef ONLINE_JUDGE // freopen("in.txt","r",stdin); // #endif // ONLINE_JUDGE int n,m,i,j,k,t; int T; read(T); int cas=1; while(T--) { printf("Case #%d:\n",cas++); init(); read(n); For(i,1,n) { int u,v; read_(u,v); vis[u]=true; addedge(v,u); } For(i,1,n+1)if(!vis[i]) { dfs(i);break; } read(m); char op[2]; build(1,1,cnt); while(m--) { scanf("%s",op); if(op[0]=='T') { int x,y; read_(x,y); update(1,1,cnt,start[x],endd[x],y); } else { int x; read(x); writeln(query(1,1,cnt,start[x])); } } } return 0; }