1. 程式人生 > >bzoj 1103

bzoj 1103

lowbit log mes void algorithm mat post blog space

先處理出整棵樹的DFS序,用樹狀數組維護 DFS序的差分序列的前綴和。

初始在每個城市的入點處+1,出點處-1,如果有土路被改造成公路,

就把它通向城市的入點處-1,出點處+1。

/**/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>

using namespace std;
const int mxn=600000;

int in[mxn],out[mxn],cnt=0;
int n,m;

//鄰接表 struct edge { int v,nxt; } e[mxn]; int hd[mxn],mct=0; void add_edge(int u,int v) { e[++mct].v=v; e[mct].nxt=hd[u]; hd[u]=mct; return; } //樹狀數組 int t[mxn]; inline int lowbit(int x) { return x&-x; } void add(int p,int v) { while(p<=cnt) { t[p]
+=v; p+=lowbit(p); } } int smm(int x) { int res=0; while(x) { res+=t[x]; x-=lowbit(x); } return res; } //DFS序 void DFS(int u,int fa) { in[u]=++cnt; for(int i=hd[u]; i; i=e[i].nxt) { int v=e[i].v; if(v==fa)continue; DFS(v,u); }
out[u]=++cnt; } int main() { scanf("%d",&n); int i,j; int u,v; for(i=1; i<n; i++) { scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } DFS(1,0); for(i=2; i<=n; i++) { add(in[i],1); add(out[i],-1); } scanf("%d",&m); char ch[5]; for(i=1; i<=m+n-1; i++) { scanf("%s",ch); if(ch[0]==A) { scanf("%d%d",&u,&v); add(in[v],-1); add(out[v],1); } else { scanf("%d",&u); printf("%d\n",smm(in[u])); } } return 0; }

bzoj 1103