标签:sea ted dir nes node ace bing pac 代码
Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional roads, such that there is exactly one path between any two pastures. Bessie, a cow who loves her grazing time, often complains about how there is no grass on the roads between pastures. Farmer John loves Bessie very much, and today he is finally going to plant grass on the roads. He will do so using a procedure consisting of M steps (1 <= M <= 100,000).
At each step one of two things will happen:
FJ will choose two pastures, and plant a patch of grass along each road in between the two pastures, or,
Farmer John is a very poor counter -- help him answer Bessie‘s questions!
给出一棵n个节点的树,有m个操作,操作为将一条路径上的边权加一或询问某条边的权值。
输入格式:
Line 1: Two space-separated integers N and M
Lines 2..N: Two space-separated integers describing the endpoints of a road.
输出格式:
4 6 1 4 2 4 3 4 P 2 3 P 1 3 Q 3 4 P 1 4 Q 2 4 Q 1 4
2 1 2
思路:
裸树剖;
来,上代码:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define maxn 100005 using namespace std; struct TreeNodeType { int l,r,dis,mid,flag; }; struct TreeNodeType tree[maxn<<2]; struct EdgeType { int to,next; }; struct EdgeType edge[maxn<<1]; int if_z,n,m,cnt,deep[maxn],f[maxn],size[maxn]; int top[maxn],id[maxn],head[maxn]; char Cget; inline void in(int &now) { now=0,if_z=1,Cget=getchar(); while(Cget>‘9‘||Cget<‘0‘) { if(Cget==‘-‘) if_z=-1; Cget=getchar(); } while(Cget>=‘0‘&&Cget<=‘9‘) { now=now*10+Cget-‘0‘; Cget=getchar(); } now*=if_z; } void search_1(int now,int fa) { int pos=cnt++; deep[now]=deep[fa]+1,f[now]=fa; for(int i=head[now];i;i=edge[i].next) { if(edge[i].to==fa) continue; search_1(edge[i].to,now); } size[now]=cnt-pos; } void search_2(int now,int chain) { int pos=0; top[now]=chain,id[now]=++cnt; for(int i=head[now];i;i=edge[i].next) { if(edge[i].to==f[now]) continue; if(size[edge[i].to]>size[pos]) pos=edge[i].to; } if(pos==0) return ; search_2(pos,chain); for(int i=head[now];i;i=edge[i].next) { if(edge[i].to==f[now]||edge[i].to==pos) continue; search_2(edge[i].to,edge[i].to); } } void tree_build(int now,int l,int r) { tree[now].l=l,tree[now].r=r; if(l==r) return ; tree[now].mid=(l+r)>>1; tree_build(now<<1,l,tree[now].mid); tree_build(now<<1|1,tree[now].mid+1,r); } void tree_change(int now,int l,int r) { if(tree[now].l==l&&tree[now].r==r) { tree[now].dis+=r-l+1; tree[now].flag++; return ; } if(tree[now].flag) { tree[now<<1].dis+=tree[now].flag*(tree[now].mid-tree[now].l+1); tree[now<<1|1].dis+=tree[now].flag*(tree[now].r-tree[now].mid); tree[now<<1].flag+=tree[now].flag,tree[now<<1|1].flag+=tree[now].flag; tree[now].flag=0; } if(l>tree[now].mid) tree_change(now<<1|1,l,r); else if(r<=tree[now].mid) tree_change(now<<1,l,r); else { tree_change(now<<1,l,tree[now].mid); tree_change(now<<1|1,tree[now].mid+1,r); } tree[now].dis=tree[now<<1].dis+tree[now<<1|1].dis; } int tree_query(int now,int l,int r) { if(tree[now].l==l&&tree[now].r==r) return tree[now].dis; if(tree[now].flag) { tree[now<<1].dis+=tree[now].flag*(tree[now].mid-tree[now].l+1); tree[now<<1|1].dis+=tree[now].flag*(tree[now].r-tree[now].mid); tree[now<<1].flag+=tree[now].flag,tree[now<<1|1].flag+=tree[now].flag; tree[now].flag=0; } if(l>tree[now].mid) return tree_query(now<<1|1,l,r); else if(r<=tree[now].mid) return tree_query(now<<1,l,r); else return tree_query(now<<1,l,tree[now].mid)+tree_query(now<<1|1,tree[now].mid+1,r); } int main() { in(n),in(m);int u,v; for(int i=1;i<n;i++) { in(u),in(v); edge[++cnt].to=v,edge[cnt].next=head[u],head[u]=cnt; edge[++cnt].to=u,edge[cnt].next=head[v],head[v]=cnt; } char type; cnt=0,search_1(1,0); cnt=0,search_2(1,1); tree_build(1,1,n); while(m--) { cin>>type;in(u),in(v); if(type==‘P‘) { while(top[u]!=top[v]) { if(deep[top[u]]<deep[top[v]]) swap(u,v); tree_change(1,id[top[u]],id[u]); u=f[top[u]]; } if(u==v) continue; if(deep[u]>deep[v]) swap(u,v); tree_change(1,id[u]+1,id[v]); } else { int pos=0; while(top[u]!=top[v]) { if(deep[top[u]]<deep[top[v]]) swap(u,v); pos+=tree_query(1,id[top[u]],id[u]); u=f[top[u]]; } if(u==v) { printf("%d\n",pos); continue; } if(deep[u]>deep[v]) swap(u,v); printf("%d\n",pos+tree_query(1,id[u]+1,id[v])); } } return 0; }
AC日记——[USACO11DEC]牧草种植Grass Planting 洛谷 P3038
标签:sea ted dir nes node ace bing pac 代码
原文地址:http://www.cnblogs.com/IUUUUUUUskyyy/p/6445568.html