fzu2082 过路费 树链剖分
来源:互联网 发布:手机淘宝神笔 增加文字 编辑:程序博客网 时间:2024/05/17 06:40
题意:中文题。。
思路:树链剖分后,在线段树上单点更新,区间查询。详见代码:
/********************************************************* file name: fzu2082.cpp author : kereo create time: 2015年01月21日 星期三 09时21分42秒*********************************************************/#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int sigma_size=26;const int N=100+50;const int MAXN=50000+50;const int inf=0x3fffffff;const double eps=1e-8;const int mod=100000000+7;#define L(x) (x<<1)#define R(x) (x<<1|1)#define PII pair<int, int>#define mk(x,y) make_pair((x),(y))int n,m,edge_cnt,cnt;int head[MAXN],sz[MAXN],son[MAXN],fa[MAXN],top[MAXN],dep[MAXN],pos[MAXN];struct Edge{ int u,v,w,next;}edge[MAXN<<1];struct node{ int l,r; ll sum;}segtree[MAXN<<2];void init(){ edge_cnt=cnt=0; memset(head,-1,sizeof(head));}void addedge(int u,int v,int w){ edge[edge_cnt].u=u; edge[edge_cnt].v=v; edge[edge_cnt].w=w; edge[edge_cnt].next=head[u]; head[u]=edge_cnt++;}void dfs1(int u,int pre,int depth){ sz[u]=1; son[u]=0; dep[u]=depth; fa[u]=pre; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v == pre) continue; dfs1(v,u,depth+1); sz[u]+=sz[v]; if(sz[son[u]]<sz[v]) son[u]=v; }}void dfs2(int u,int tp){ pos[u]=cnt++; top[u]=tp; if(son[u]!=0) dfs2(son[u],top[u]); for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v == fa[u] || v == son[u]) continue; dfs2(v,v); }}void build(int rt,int l,int r){ segtree[rt].l=l; segtree[rt].r=r; segtree[rt].sum=0; if(l == r) return ; int mid=(l+r)>>1; build(L(rt),l,mid); build(R(rt),mid+1,r);}void push_up(int rt){ segtree[rt].sum=segtree[L(rt)].sum+segtree[R(rt)].sum;}void update(int rt,int p,int x){ if(segtree[rt].l == segtree[rt].r){ segtree[rt].sum=x; return ; } int mid=(segtree[rt].l+segtree[rt].r)>>1; if(p<=mid) update(L(rt),p,x); else update(R(rt),p,x); push_up(rt);}ll query(int rt,int l,int r){ if(segtree[rt].l == l && segtree[rt].r == r) return segtree[rt].sum; int mid=(segtree[rt].l+segtree[rt].r)>>1; if(r<=mid) return query(L(rt),l,r); else if(l>mid) return query(R(rt),l,r); else return query(L(rt),l,mid)+query(R(rt),mid+1,r);}ll solve(int u,int v){ ll ans=0; while(top[u]!=top[v]){ if(dep[top[u]]<dep[top[v]]) swap(u,v); ans+=query(1,pos[top[u]],pos[u]); u=fa[top[u]]; } if(dep[u]>dep[v]) swap(u,v); if(u!=v) ans+=query(1,pos[u]+1,pos[v]); return ans;}int main(){ while(~scanf("%d%d",&n,&m)){ init(); for(int i=1;i<n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } dfs1(1,1,1); dfs2(1,1); build(1,1,n-1); for(int i=0;i<edge_cnt;i+=2){ int u=edge[i].u,v=edge[i].v,w=edge[i].w; if(dep[u]<dep[v]) swap(u,v); update(1,pos[u],w); } for(int i=0;i<m;i++){ int id,u,v; scanf("%d",&id); if(id == 0){ int x,w; scanf("%d%d",&x,&w); x=(x-1)*2; u=edge[x].u; v=edge[x].v; if(dep[u]<dep[v]) swap(u,v); update(1,pos[u],w); } else{ scanf("%d%d",&u,&v); printf("%lld\n",solve(u,v)); } } }return 0;}
0 0
- fzu2082 过路费 树链剖分
- fzu2082 过路费(树链剖分)
- FZU2082 过路费(树链剖分线段树)
- fzu2082 过路费 【线段树+树链剖分】
- FZU2082-过路费
- 树链剖分线段更新模板fzu2082过路费
- fzu2082(树链剖分)
- FZU2082 树链剖分 对边操作
- FZU2082 树链剖分(单点更新区间求值)
- 【树链剖分】 FZU 2082 过路费
- fzu 2082 过路费(树链剖分)
- FZU 2082 过路费 (树链剖分)
- FZU 2082 过路费 树链剖分
- fzoj 2082 过路费 【树链剖分】
- FZU 2082过路费 树链剖分
- FZU 2082 过路费 [树链剖分]
- 过路费
- 过路费
- SpringMVC学习之@ModelAttribute运用详解
- boost::filesystem::status: Permission denied: "/home/congleetea/.gvfs"的解决办法
- 素因子分解:nefu118(n!后面有多少个0)+ nefu119 (组合素数)
- 第四章 Android开发三大基石—Activity、Service和Handler(4)
- uname系统调用
- fzu2082 过路费 树链剖分
- [转]无线性能优化方法
- 中介者模式
- Myeclipse搭建Maven开发环境
- fstat函数及struct stat结构
- SQL2008 新建维护计划 调用的目标发生了异常 从 IClassFactory 为 CLSID 为 {....} 的 COM 组件创建实例失败,原因是出现以下错误:c001f011.(Micros
- java线程池的使用
- 抽象类和抽象函数_23
- python网络编程报错socket.error: [Errno 9] Bad file descriptor