树链剖分
2015-08-10 16:05
357 查看
做了两个题找了找感觉。
分别是 SPOJ375 和 codeforces191c,都是用线段树维护的。其实第二题不用线段树也可以。。关键是理解树链剖分的过程,然后找合适的数据结构去维护它。
SPOJ375:
codeforces191c:
分别是 SPOJ375 和 codeforces191c,都是用线段树维护的。其实第二题不用线段树也可以。。关键是理解树链剖分的过程,然后找合适的数据结构去维护它。
SPOJ375:
等下。。。
codeforces191c:
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; struct Node { int l,r,s,lazy; }Seg[800005]; struct Edge { int u,v,w; int next; }map[400005]; Edge f[200005]; int head[400005],t,n,k,ans; int num=0;//�߶����б�� int fa[200005],siz[200005],dep[200005],son[200005],top[200005],w[200005],m[200005]; inline void init() { memset(head,0,sizeof(head)); t=1; } inline void build(int v,int l,int r) { Seg[v].l=l;Seg[v].r=r; if(l==r) { Seg[v].s=0; return ; } int mid=(l+r)>>1; build(v*2,l,mid); build(v*2+1,mid+1,r); } inline void update(int l,int r,int v) { Seg[v].s+=(r-l+1)*1; if(l==Seg[v].l&&r==Seg[v].r) { Seg[v].lazy+=1; return ; } if(Seg[v].lazy!=0) { Seg[2*v].lazy+=Seg[v].lazy; Seg[2*v+1].lazy+=Seg[v].lazy; Seg[2*v].s+=(Seg[2*v].r-Seg[2*v].l+1)*Seg[v].lazy; Seg[2*v+1].s+=(Seg[2*v+1].r-Seg[2*v+1].l+1)*Seg[v].lazy; Seg[v].lazy=0; } int mid=(Seg[v].l+Seg[v].r)>>1; if(r<=mid) update(l,r,v*2); else { if(l>=mid+1) update(l,r,v*2+1); else { update(l,mid,2*v); update(mid+1,r,2*v+1); } } } inline void find(int l,int r,int v) { if(Seg[v].l==l&&Seg[v].r==r) { ans+=Seg[v].s; return ; } if(Seg[v].lazy!=0) { Seg[2*v].lazy+=Seg[v].lazy; Seg[2*v+1].lazy+=Seg[v].lazy; Seg[2*v].s+=(Seg[2*v].r-Seg[2*v].l+1)*Seg[v].lazy; Seg[2*v+1].s+=(Seg[2*v+1].r-Seg[2*v+1].l+1)*Seg[v].lazy; Seg[v].lazy=0; } int mid=(Seg[v].l+Seg[v].r)>>1; if(r<=mid) find(l,r,2*v); else { if(l>=mid+1) find(l,r,2*v+1); else { find(l,mid,2*v); find(mid+1,r,2*v+1); } } } inline void add(int u,int v,int w) { map[t].u=u; map[t].v=v; map[t].w=w; map[t].next=head[u]; head[u]=t;t++; } inline void dfs1(int now,int pre) { siz[now]=1;fa[now]=pre;son[now]=0;dep[now]=dep[pre]+1; int i,v; for(i=head[now];i;i=map[i].next) { v=map[i].v; if(v!=pre) { dfs1(v,now); siz[now]+=siz[v]; if(siz[son[now]]<siz[v]) son[now]=v; } } } inline void dfs2(int now,int tp) { w[now]=++num; m[num]=now; top[now]=tp; if(son[now]) dfs2(son[now],tp); int i,v; for(i=head[now];i;i=map[i].next) { v=map[i].v; if(son[now]!=v&&v!=fa[now]) dfs2(v,v); } } inline void modify(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); update(w[top[x]],w[x],1); x=fa[top[x]]; } if(x==y) return ; if(dep[x]>dep[y]) swap(x,y); update(w[x]+1,w[y],1); } inline void query(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); find(w[top[x]],w[x],1); x=fa[top[x]]; } if(x==y) return ; if(dep[x]>dep[y]) swap(x,y); find(w[x]+1,w[y],1); } int main() { int i,a,b;init(); scanf("%d",&n); for(i=1;i<n;i++) { scanf("%d%d",&a,&b); add(a,b,0); add(b,a,0); f[i].u=a;f[i].v=b; } build(1,1,n); dfs1(1,1); dfs2(1,1); scanf("%d",&k); for(i=1;i<=k;i++) { scanf("%d%d",&a,&b); modify(a,b); } for(i=1;i<=n-1;i++) { ans=0; int x=f[i].u;int y=f[i].v; query(x,y); if(i!=n-1) printf("%d ",ans); else printf("%d\n",ans); } return 0; }
相关文章推荐
- UVA 707 - Robbery【记忆化搜索】
- QT5的移植与错误总结
- 混合高斯模型(Mixtures of Gaussians)和EM算法
- hdu5353 Average
- 栈的顺序存储结构
- hdu 1028 Ignatius and the Princess III +hdu 1085 Holding Bin-Laden Captive!(母函数)
- nginx + unicorn 配置
- 76 php 页面数据格式化
- 关于升级Xcode版本后插件不能用的问题解决
- js常用正则表达式
- TCP echo demo
- myeclipse安装SVN插件
- java的变量和方法,实例化new
- IOS-开发小记 填坑之旅
- URAL 1519 基础插头DP
- sts 框架新建以及 网站部署
- 二叉树
- sql优化
- python装饰器
- POJ 题目3667 Hotel(线段树,区间更新查询,求连续区间)