HDU 5893 List wants to travel
来源:互联网 发布:网络信号传输增强器 编辑:程序博客网 时间:2024/05/22 08:20
HDU 5893 List wants to travel
树链剖分,边权
题目
给出2种操作
- 修改u到v的路径上的边的颜色为c
- 查询u到v的路径上有多少段颜色
思路
根bzoj2243差不多,就是把点权改成边权。把边权下放到深度大的点的点权。维护起来没有想的复杂。
先往重链头跳,跳完判断一下l是否跟r一样。一样说明汇合,不需要继续查了。否则查的时候要避开端点,可以查重儿子,看代码吧。
代码
树链剖分多组样例,记得把hson和depth数组清掉。
#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cstdlib>#include<iostream>#include<cmath>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define M(a,b) memset(a,b,sizeof(a))using namespace std;const int MAXN=50007;typedef long long LL;struct Edge{ int to, ne, val;}G[MAXN*2];int head[MAXN];int Val[MAXN], Hson[MAXN], SonAmount[MAXN], Father[MAXN], Depth[MAXN];int Dfsnum[MAXN], TreeValue[MAXN], TopOfHeavyChain[MAXN];int dfscount, edgenum;void AddEdge(int from, int to, int v){ G[edgenum].to=to, G[edgenum].val=v, G[edgenum].ne=head[from];head[from]=edgenum++; G[edgenum].to=from, G[edgenum].val=v, G[edgenum].ne=head[to];head[to]=edgenum++;}void init(){ M(head, -1);M(G, 0); M(Hson, 0);M(Depth, 0); dfscount=0;edgenum=1;Val[1]=0;Father[1]=1;Depth[1]=1;}void dfs1(int n){ SonAmount[n]=1; for(int i=head[n];~i;i=G[i].ne) { int to=G[i].to; if(Depth[to]) continue; Depth[to]=Depth[n]+1; Val[to]=G[i].val;//边权转化为点权 Father[to]=n; dfs1(to); SonAmount[n]+=SonAmount[to]; if(SonAmount[to]>SonAmount[Hson[n]]) Hson[n]=to; } return;}void dfs2(int n, int prev){ Dfsnum[n]=++dfscount; TreeValue[dfscount]=Val[n]; TopOfHeavyChain[n]=prev; if(!Hson[n]) return; dfs2(Hson[n], prev); for(int i=head[n];~i;i=G[i].ne) { int to=G[i].to; if(to==Hson[n]||to==Father[n]) continue; dfs2(to, to); }}struct Stree{ int lcol, rcol; int lazy;int num; Stree() { lcol=rcol=lazy=-1;num=0; } void init() { lcol=rcol=lazy=-1;num=0; }}stree[MAXN<<2];inline void pushup(int rt){ stree[rt].num=stree[rt<<1].num+stree[rt<<1|1].num; if(stree[rt<<1].rcol==stree[rt<<1|1].lcol) stree[rt].num--; stree[rt].lcol=stree[rt<<1].lcol, stree[rt].rcol=stree[rt<<1|1].rcol;}inline void pushdown(int rt){ if(stree[rt].lazy!=-1) { int c=stree[rt].lazy;stree[rt].lazy=-1; stree[rt<<1].lazy=stree[rt<<1|1].lazy=c; stree[rt<<1].num=stree[rt<<1|1].num=1; stree[rt<<1].lcol=stree[rt<<1|1].lcol=c; stree[rt<<1].rcol=stree[rt<<1|1].rcol=c; }}void build(int l, int r, int rt){ stree[rt].init(); if(l==r) { stree[rt].lcol=stree[rt].rcol=TreeValue[l];stree[rt].num=1;return; } int mid=(l+r)>>1; build(lson), build(rson); pushup(rt);}void update(int L, int R, int c, int l, int r, int rt){ if(L<=l&&r<=R) { stree[rt].lcol=stree[rt].rcol=c; stree[rt].lazy=c; stree[rt].num=1; return; } pushdown(rt); int mid=(l+r)>>1; if(L<=mid) update(L, R, c, lson); if(mid<R) update(L, R, c, rson); pushup(rt);}Stree query(int L, int R, int l, int r, int rt){ if(L<=l&&r<=R) return stree[rt]; pushdown(rt); int mid=(l+r)>>1; if(R<=mid) return query(L, R, lson); else if(mid<L) return query(L, R, rson); else { Stree lres=query(L, R, lson); Stree rres=query(L, R, rson); Stree res; res.num=lres.num+rres.num-(lres.rcol==rres.lcol); res.lcol=lres.lcol, res.rcol=rres.rcol; return res; }}void solveup(int n){ int l, r, c;scanf("%d%d%d", &l, &r, &c); int fl=TopOfHeavyChain[l], fr=TopOfHeavyChain[r]; while(fl!=fr) { if(Depth[fl]>Depth[fr]) { update(Dfsnum[fl], Dfsnum[l], c, 1, n, 1); l=Father[fl];fl=TopOfHeavyChain[l]; } else { update(Dfsnum[fr], Dfsnum[r], c, 1, n, 1); r=Father[fr];fr=TopOfHeavyChain[r]; } } if(l==r) return; if(Depth[l]>Depth[r]) update(Dfsnum[Hson[r]], Dfsnum[l], c, 1, n, 1); else update(Dfsnum[Hson[l]], Dfsnum[r], c, 1, n, 1);}void solvequ(int n){ int l, r;scanf("%d%d", &l, &r); //if(l==r) { printf("-1\n");return; } int fl=TopOfHeavyChain[l], fr=TopOfHeavyChain[r]; int lcol=-1, rcol=-1, res=0; while(fl!=fr) { if(Depth[fl]>Depth[fr]) { Stree lc=query(Dfsnum[fl], Dfsnum[l], 1, n, 1); res+=lc.num; if(lcol==lc.rcol) res--; lcol=lc.lcol; l=Father[fl]; fl=TopOfHeavyChain[l]; } else { Stree rc=query(Dfsnum[fr], Dfsnum[r], 1, n, 1); res+=rc.num; if(rcol==rc.rcol) res--; rcol=rc.lcol; r=Father[fr]; fr=TopOfHeavyChain[r]; } } if(l!=r) { if(Depth[l]>Depth[r]) { Stree lc=query(Dfsnum[Hson[r]], Dfsnum[l], 1, n, 1); res+=lc.num; if(lcol==lc.rcol) res--; if(rcol==lc.lcol) res--; } else { Stree rc=query(Dfsnum[Hson[l]], Dfsnum[r], 1, n, 1); res+=rc.num; if(lcol==rc.lcol) res--; if(rcol==rc.rcol) res--; } } else { res-=(lcol==rcol); } printf("%d\n", res);}int main(){ //freopen("in.txt", "r", stdin); //freopen("ou1.txt", "w", stdout); int n, m; while(scanf("%d%d", &n, &m)==2) { init(); for(int i=1;i<n;i++) { int u, v, c;scanf("%d%d%d", &u, &v, &c); AddEdge(u, v, c); } dfs1(1), dfs2(1, 1);build(1, n, 1); while(m--) { char s[10]; scanf("%s", s); if(s[0]=='Q') solvequ(n); else solveup(n); } } //system("pause"); return 0;}
阅读全文
0 0
- Hdu-5893 List wants to travel(树链剖分)
- [树链剖分] HDU 5893 List wants to travel
- HDU 5893 List wants to travel
- HDU 5893 List wants to travel 树链剖分
- hdu 5893 List wants to travel
- HDU 5893 List wants to travel
- hdu 5893 List wants to travel 树链剖分 +线段树
- [HDU 5893] List wants to travel (树链剖分+区间合并)
- HDU 5893 List wants to travel 树链剖分 边权剖分
- HDU 5893 List wants to travel(树链剖分+区间合并)
- HDU 5893 List wants to travel 【线段树+树链剖分】
- hdu 5893 List wants to travel 树链剖分求区间段数
- List wants to travel
- hdu5893 List wants to travel
- hdu 5893 List wants to travel 2016ACM/ICPC沈阳赛区网络赛1002
- 2016 ACM/ICPC Asia Regional Shenyang Online HDU 5893 List wants to travel
- BZOJ 2243/HDU 5893([SDOI2011]染色/List wants to travel-树链剖分点权/边权)
- HDU 5893 List wants to travel (树链剖分,线段树区间合并)
- HDU6127 Hard challenge【几何】
- Libevent-2.1.8源码分析——锁和线程
- 【JavaSE笔记】IO(四)字符流
- Canny边缘检测算法
- eth0未启动或找不到设备
- HDU 5893 List wants to travel
- poj3181(dp优化递推关系式)
- 树分枝问题(Kolakoski)
- Netty 实现HTTP文件服务器
- Harmonic Value Description HDU
- HDU 1028 Ignatius and the Princess III(DP,整数划分)
- ubuntu下安装redis
- [leetcode] 43. Multiply Strings(大数相乘)
- 类的加载,连接和初始化