POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )
来源:互联网 发布:非洲人眼中的中国知乎 编辑:程序博客网 时间:2024/05/21 00:20
POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )
题意分析
给出n个点,m个询问,和当前位置pos。
先给出n-1条边,u->v以及边权w。
然后有m个询问,询问分2种:
一是讲第i条边的边权修改为w。
二是询问从当前位置走到点x经过的边权和(下次询问就是从这点开始)。
边权的树链剖分,其实和点权的差不多。对于一条边u-v,及其边权w,在建立线段树的时候,将深度大的点,当做其边权w,如dep[u]>dep[v],就令newid[u] = w。这样一来,将边权问题转化为点权问题,需要注意的,就是在查询的时候,对于lca的处理。
处理方法也很简单,首先判断:当深度大的网上爬,爬到一定程度的时候,是否两点已经重合,若是的话,直接返回值就好。 否则,就用查询[深度小的儿子]到[深度大的这段区间],并将结果累加到ans中。
代码总览
#include <cstdio>#include <cstring>#include <algorithm>#define ll int#define nmax 100820using namespace std;int fa[nmax],son[nmax],sz[nmax],newid[nmax],hashback[nmax],dep[nmax],top[nmax];int num,tot,head[nmax];struct edge{ int to; int next;}edg[nmax<<1];struct tree{ int l,r,val; int mid(){ return (l+r)>>1; }}tree[nmax<<2];struct mess{ int u,v,w;}mes[nmax];void add(int u, int v){ edg[tot].to = v; edg[tot].next = head[u]; head[u] = tot++;}void dfsFirst(int rt, int f,int d){ dep[rt] = d; fa[rt] = f; sz[rt] = 1; for(int i = head[rt]; i!= -1; i = edg[i].next){ int nxt = edg[i].to; if(nxt != f){ dfsFirst(nxt,rt,d+1); sz[rt]+=sz[nxt]; if(son[rt] == -1 || sz[nxt] > sz[son[rt]]){ son[rt] = nxt; } } }}void dfsSecond(int rt, int tp){ top[rt] = tp; newid[rt] = ++num; if(son[rt] == -1) return; dfsSecond(son[rt],tp); for(int i = head[rt];i != -1; i = edg[i].next){ int nxt = edg[i].to; if(nxt != son[rt] && nxt != fa[rt]) dfsSecond(nxt,nxt); }}void init(){ memset(tree,0,sizeof tree); memset(head,-1,sizeof head); memset(son,-1,sizeof son); memset(edg,0,sizeof edg); tot = num = 0;}void PushUp(int rt){ tree[rt].val = tree[rt<<1].val + tree[rt<<1|1].val;}void Build(int l, int r, int rt){ tree[rt].l = l; tree[rt].r = r; if(l == r){ return; } Build(l,tree[rt].mid(),rt<<1); Build(tree[rt].mid()+1,r,rt<<1|1); PushUp(rt);}void UpdatePoint(int val, int pos, int rt){ if(tree[rt].l == tree[rt].r){ tree[rt].val = val ; return; } if(pos <= tree[rt].mid()) UpdatePoint(val,pos,rt<<1); else UpdatePoint(val,pos,rt<<1|1); PushUp(rt);}int QuerySUM(int l,int r,int rt){; if(l>tree[rt].r || r<tree[rt].l) return 0; if(l <= tree[rt].l && tree[rt].r <= r) return tree[rt].val; return QuerySUM(l,r,rt<<1) + QuerySUM(l,r,rt<<1|1);}long long Find_SUM(int x, int y){ int tx = top[x],ty =top[y]; long long ans = 0; while(tx != ty){ if(dep[tx] < dep[ty]){ swap(x,y); swap(tx,ty); } ans += QuerySUM(newid[tx],newid[x],1); x = fa[tx]; tx = top[x]; } if(x == y) return ans; if(dep[x] > dep[y]) swap(x,y); ans += QuerySUM(newid[son[x]],newid[y],1); return ans;}int n,m;int main(){// freopen("in.txt","r",stdin); int m,x,y,posnow; int op; while(scanf("%d %d %d",&n,&m,&posnow)!=EOF){ init(); for(int i =1;i<=n-1;++i){ scanf("%d %d %d",&mes[i].u,&mes[i].v,&mes[i].w); add(mes[i].u,mes[i].v); add(mes[i].v,mes[i].u); } num = 0; dfsFirst(1,0,1); dfsSecond(1,1); Build(1,n,1); for(int i = 1;i<=n-1;++i){ if(dep[mes[i].u] > dep[mes[i].v])// v is bigger; swap(mes[i].u,mes[i].v); UpdatePoint(mes[i].w,newid[mes[i].v],1); }// printf("MESSA ID DATA FA SON SIZE DEEP NEWID TOP SEGHASH\n");// for(int i = 1;i<=n;++i){// printf("DEBUG %5d %5d %5d %5d %5d %5d %5d %5d %5d\n",i,data[i],fa[i],son[i],sz[i],dep[i],newid[i],top[i],seghash[i]);// }//// printf("MESSA ID val\n");// for(int i = 1;i<=n;++i){// printf("DEBUF %d %d\n",i,QuerySUM(i,i,1));// } for(int i = 0;i<m;++i){ scanf("%d",&op); if(op == 1){//change scanf("%d %d",&x,&y); x = newid[mes[x].v]; UpdatePoint(y,x,1); }else {//ask scanf("%d",&x); printf("%lld\n",Find_SUM(posnow,x)); posnow = x; } } } return 0;}
阅读全文
1 0
- POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )
- POJ 2763 Housewife Wind (树链剖分+线段树)
- POJ 2763 Housewife Wind (LCA+线段树)
- poj 2763 Housewife Wind(线段树+树剖)
- poj 2763 Housewife Wind 【树链剖分维护树上权值和】
- POJ 2763Housewife Wind(树链剖分+线段树点更新-区间查询+入边)
- POJ 2763 Housewife Wind
- POJ 2763 Housewife Wind
- poj 2763 Housewife Wind
- POJ 2763 Housewife Wind
- POJ 2763 Housewife Wind
- poj 2763 Housewife Wind
- POJ 2763 Housewife Wind
- POJ 2763 Housewife Wind
- POJ 2763 Housewife Wind
- poj 2763 Housewife Wind
- poj 2763 Housewife Wind(树链剖分)
- POJ 2763 Housewife Wind 树链剖分
- HDU 5839 Special Tetrahedron(几何+暴力)
- 最短路(Bellman队列优化)
- 小型游戏《笑傲江湖之精忠报国》全过程_04
- 每日MySQL之021:EXPLAIN输出中的Join Types
- hdu6103Kirinriki(尺取法)
- POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )
- C++ 字符串转换
- 模拟 最长上升子串
- POJ 3074 Sudoku 转化精确覆盖问题DLX
- XlistView 加载头部ViewPager 网络请求数据 存入数据库
- 量化交易,未来互联网金融的发展趋势
- sleep,yield,join,notify,wait,notifyAll区别
- MAC上创建局域网git项目仓库
- hiho 1553区间统计 莫队算法+分块思想