【BZOJ 1130】【POI 2007】大都市meg【树链剖分】
2017-04-04 21:44
330 查看
Description
昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且,对于每个村庄,它到比特堡的路径恰好只经过编号比它的编号小的村庄。另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。现在,越来越多的土路被改造成了公路。 Blue Mary想起了在改造期间她送信的经历。她从比特堡出发,需要去某个村庄,并且在两次送信经历的间隔期间,有某些土路被改造成了公路。现在Blue Mary需要你的帮助:计算出每次送信她需要走过的土路数目。Input
第一行是一个数n(1 < = n < = 2 50000)。以下n-1行,每行两个整数a,b。以下一行包含一个整数m(1 < = m < = 2 50000),表示Blue Mary曾经在改造期间送过m次信。以下n+m-1行,每行有两种格式的若干信息,表示按时间先后发生过的n+m-1次事件:若这行为 A a b(a若这行为 W a, 则表示Blue Mary曾经从比特堡送信到村庄a。Output
有m行,每行包含一个整数,表示对应的某次送信时经过的土路数目。题解
裸树链剖分,没什么好说的。除了要注意输入是在遇到m个w后停止。
代码
#include<cstdio> #include<cstring> #include<algorithm> #define N 250010 using namespace std; struct node{int to,next;}e[N*2]; int head ,m,tim,n; int size ,son ,top ,fa ,tid ,dep ; void init() { memset(head,0,sizeof(head)); memset(son,-1,sizeof(son)); tim = m = 0; } void add_edge(int from,int to) { e[++m].next = head[from]; head[from] = m; e[m].to = to; } void dfs1(int v,int pa,int d) { size[v] = 1; fa[v] = pa; dep[v] = d; for(int i = head[v];i;i=e[i].next) if(e[i].to != pa) { dfs1(e[i].to,v,d+1); size[v] += size[e[i].to]; if(son[v] == -1 || size[son[v]] < size[e[i].to]) son[v] = e[i].to; } } void dfs2(int v,int tp) { top[v] = tp; tid[v] = ++tim; if(son[v] == -1) return; dfs2(son[v],tp); for(int i = head[v];i;i=e[i].next) if(e[i].to != fa[v] && e[i].to != son[v]) dfs2(e[i].to,e[i].to); } #define lson o << 1 #define rson o << 1 | 1 int sum[N << 2]; void build(int o,int l,int r) { if(l == r) {sum[o] = 1; return;} int mid = (l+r)>>1; build(lson,l,mid); build(rson,mid+1,r); sum[o] = sum[lson] + sum[rson]; } void change(int o,int l,int r,int pos) { if(l == r) {sum[o] = 0; return;} int mid = (l+r)>>1; if(pos <= mid) change(lson,l,mid,pos); else change(rson,mid+1,r,pos); sum[o] = sum[lson] + sum[rson]; } int query(int o,int l,int r,int ll,int rr) { if(ll <= l && rr >= r) return sum[o]; int mid = (l+r)>>1,ans = 0; if(ll <= mid) ans += query(lson,l,mid,ll,rr); if(rr > mid) ans += query(rson,mid+1,r,ll,rr); return ans; } int Query(int x,int y) { int ans = 0; while(top[x] != top[y]) { if(dep[top[x]] < dep[top[y]]) swap(x,y); ans += query(1,1,n,tid[top[x]],tid[x]); x = fa[top[x]]; } if(dep[x] > dep[y]) swap(x,y); ans += query(1,1,n,tid[x]+1,tid[y]); return ans; } int main() { char opt[3]; int u,v; scanf("%d",&n); init(); for(int i = 1;i < n;i++) { scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } dfs1(1,0,0); dfs2(1,1); build(1,1,n); scanf("%d",&m); int z = 0; while(z < m) { scanf("%s%d",opt,&u); if(opt[0] == 'A') { 4000 scanf("%d",&v); if(u > v) swap(u,v); change(1,1,n,tid[v]); } else {z++; printf("%d\n",Query(1,u));} } return 0; }
相关文章推荐
- BZOJ 1103 POI 2007 大都市meg 树状数组
- BZOJ 1103: [POI2007]大都市meg 树链剖分, 树状数组+DFS序
- [BZOJ 1103][POI 2007]大都市(DFS求拓扑序+树状数组)
- bzoj 1103: [POI2007]大都市meg(树链剖分)
- 【POI 2007】Megalopolis大都市(meg)
- BZOJ 1103: [POI2007]大都市meg( 树链剖分 )
- 【BZOJ1103】[POI2007]大都市meg【树链剖分】【线段树】【或 树状数组 + dfs序】
- BZOJ1103: [POI2007]大都市meg
- BZOJ 1103 [POI2007]大都市meg
- BZOJ1103: [POI2007]大都市meg
- [BZOJ 1101] POI 2007 Zap · 莫比乌斯 & 分块 超详细题解
- bzoj1103: [POI2007]大都市meg
- Bzoj1103 [POI2007]大都市meg
- bzoj1103【POI2007】大都市meg
- Zap [bzoj 1101,POI 2007]
- BZOJ 1103: [POI2007]大都市meg [DFS序 树状数组]
- [Bzoj1103][POI2007]大都市meg (dfs序+ 树状数组)
- 数据结构(线段树):BZOJ 1103 [POI2007]大都市meg
- 【BZOJ 1103】 [POI2007]大都市meg
- bzoj1103 [POI2007]大都市meg(树+差分+树状数组)