bzoj1103: [POI2007]大都市meg(树链剖分)
来源:互联网 发布:有出售二手房软件 编辑:程序博客网 时间:2024/05/17 07:19
题目传送门
模板题吧。
没学过树链剖分看这里
这道题大概也差不多。
因为这道题是维护边的权(是土路值为1,公路值为0)
求得就是某一个点到1的边权和。
那么我们要把边的值赋值到点上如何做呢?
就把每条边的权值赋值到下面的点上。
代码里面有详细解释。
代码实现:
#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>using namespace std;struct node { int x,y,next;}a[510000];int len,last[251000];void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len;}int n,fa[251000],son[251000],tot[251000],dep[251000];void pre_tree_node(int x) { son[x]=0;tot[x]=1; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=fa[x]) { fa[y]=x; dep[y]=dep[x]+1; pre_tree_node(y); if(tot[son[x]]<tot[y]) son[x]=y; tot[x]+=tot[y]; } }}int z,ys[251000],top[251000]; //ys[x]表示x与x的父亲相连的那条边的编号void pre_tree_edge(int x,int tp) { ys[x]=++z;top[x]=tp; if(son[x]!=0) pre_tree_edge(son[x],tp); for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=fa[x]&&y!=son[x]) pre_tree_edge(y,y); }}struct trnode { int l,r,lc,rc,c;}tr[1100000];int trlen;void bt(int l,int r) { int now=++trlen; tr[now].l=l;tr[now].r=r; tr[now].lc=tr[now].rc=-1; tr[now].c=0; if(l<r) { int mid=(l+r)/2; tr[now].lc=trlen+1;bt(l,mid); tr[now].rc=trlen+1;bt(mid+1,r); }}void change(int now,int x,int k) { if(tr[now].l==tr[now].r) { tr[now].c=k;return ; } int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; if(x<=mid) change(lc,x,k); else change(rc,x,k); tr[now].c=tr[lc].c+tr[rc].c; //因为这道题求和,所以把两个区间的和加起来}int findsum(int now,int l,int r) { if(tr[now].l==l&&tr[now].r==r) return tr[now].c; int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; if(r<=mid) return findsum(lc,l,r); else if(l>mid) return findsum(rc,l,r); else return findsum(lc,l,mid)+findsum(rc,mid+1,r);}int solve(int x,int y) { int tx=top[x],ty=top[y],ans=0; while(tx!=ty) { if(dep[tx]>dep[ty]) { swap(tx,ty);swap(x,y); } ans+=findsum(1,ys[ty],ys[y]); y=fa[ty];ty=top[y]; } if(x==y) return ans; if(dep[x]>dep[y]) swap(x,y); return ans+findsum(1,ys[son[x]],ys[y]);}struct bian { int x,y;}e[251000];int main() { int n,m;scanf("%d",&n); len=0;memset(last,0,sizeof(last)); for(int i=1;i<n;i++) { scanf("%d%d",&e[i].x,&e[i].y); ins(e[i].x,e[i].y); ins(e[i].y,e[i].x); } dep[1]=0;fa[1]=0;pre_tree_node(1); z=0;pre_tree_edge(1,1); trlen=0;bt(1,z); for(int i=1;i<n;i++) { if(dep[e[i].x]>dep[e[i].y]) swap(e[i].x,e[i].y); change(1,ys[e[i].y],1); //赋值到深度较大的。 } scanf("%d",&m); for(int i=1;i<=n+m-1;i++) { int x,y;char s[5]; scanf("%s%d",s+1,&x); if(s[1]=='A') { scanf("%d",&y); if(dep[x]>dep[y]) swap(x,y); change(1,ys[y],0); //改变权值咯 } else printf("%d\n",solve(1,x)); //求和咯 } return 0;}
阅读全文
0 0
- bzoj1103: [POI2007]大都市meg(树链剖分)
- bzoj1103【POI2007】大都市meg
- 【POI2007】【BZOJ1103】大都市meg
- bzoj1103[POI2007]大都市meg
- 【BZOJ1103】【POI2007】大都市meg
- bzoj1103: [POI2007]大都市meg
- 【BZOJ1103】[POI2007]大都市meg
- bzoj1103: [POI2007]大都市meg
- bzoj1103 [POI2007]大都市meg
- BZOJ1103: [POI2007]大都市meg
- bzoj1103 [POI2007]大都市meg
- BZOJ1103: [POI2007]大都市meg
- 8.3 bzoj1103 [POI2007]大都市meg
- BZOJ1103 [POI2007]大都市meg 【树剖】
- [BZOJ1103][POI2007]大都市meg(dfs序+bit||链剖)
- 【bzoj1103】【POI2007】【大都市】【meg】【人工栈】
- 【bzoj1103】[POI2007]大都市meg DFS序
- bzoj 1103: [POI2007]大都市meg(树链剖分)
- 查询set、dict、dict.keys()的速度对比
- div自适应高度
- C语言笔记(3)
- SSH远程登录原理
- SQL Plan Management (1)
- bzoj1103: [POI2007]大都市meg(树链剖分)
- 依赖注入与对象间关系
- 设计模式11-组合模式
- MOOC清华《VC++面向对象与可视化程序设计》第2章:编程作业-渐变图形的绘制(“万花筒”程序)
- [博弈 && Splay维护DFS序]BZOJ3729 .Gty的游戏
- Oracle练习题总结
- GOOGLE ON-CAMPUS 面试经验
- 谈谈Polya那些事
- UBUNTU 关闭iptables的方法