HDU5893 List wants to travel (树链剖分 + 线段树) 2016 ACM/ICPC Asia Regional Shenyang Online
来源:互联网 发布:淘宝网pu羽绒服 编辑:程序博客网 时间:2024/05/21 20:29
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5893
题目大意:一棵树,两种操作:改变路径上的颜色,和询问路径上有多少段相邻颜色不同。
解题思路:树链剖分,跟BZOJ2243题目几乎一样,只不过这里是边权,把边权转化成点权,边权赋予给深度大的节点。然后用线段树维护。
/* ***********************************************┆ ┏┓ ┏┓ ┆┆┏┛┻━━━┛┻┓ ┆┆┃ ┃ ┆┆┃ ━ ┃ ┆┆┃ ┳┛ ┗┳ ┃ ┆┆┃ ┃ ┆┆┃ ┻ ┃ ┆┆┗━┓ 马 ┏━┛ ┆┆ ┃ 勒 ┃ ┆ ┆ ┃ 戈 ┗━━━┓ ┆┆ ┃ 壁 ┣┓┆┆ ┃ 的草泥马 ┏┛┆┆ ┗┓┓┏━┳┓┏┛ ┆┆ ┃┫┫ ┃┫┫ ┆┆ ┗┻┛ ┗┻┛ ┆************************************************ */#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <bitset>using namespace std;#define rep(i,a,b) for (int i=(a),_ed=(b);i<=_ed;i++)#define per(i,a,b) for (int i=(b),_ed=(a);i>=_ed;i--)#define pb push_back#define mp make_pairconst int inf_int = 2e9;const long long inf_ll = 2e18;#define inf_add 0x3f3f3f3f#define mod 1000000007#define LL long long#define ULL unsigned long long#define MS0(X) memset((X), 0, sizeof((X)))#define SelfType intSelfType Gcd(SelfType p,SelfType q){return q==0?p:Gcd(q,p%q);}SelfType Pow(SelfType p,SelfType q){SelfType ans=1;while(q){if(q&1)ans=ans*p;p=p*p;q>>=1;}return ans;}#define Sd(X) int (X); scanf("%d", &X)#define Sdd(X, Y) int X, Y; scanf("%d%d", &X, &Y)#define Sddd(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)#define reunique(v) v.resize(std::unique(v.begin(), v.end()) - v.begin())#define all(a) a.begin(), a.end#define mem(x,v) memset(x,v,sizeof(x))typedef pair<int, int> pii;typedef pair<long long, long long> pll;typedef vector<int> vi;typedef vector<long long> vll;inline int read(){int ra,fh;char rx;rx=getchar(),ra=0,fh=1;while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();if(rx=='-')fh=-1,rx=getchar();while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;}//#pragma comment(linker, "/STACK:102400000,102400000")const int N = 40005;int n,m;int a[N*4];struct Edge{ int to,from,nx,w;}edge[N*2];int head[N],cnt;void addedge(int u,int v,int w){ edge[cnt] = Edge{v,u,head[u],w}; head[u] = cnt++;}/*树链剖分*/int top[N],fa[N],son[N],dep[N];int siz[N],tot,tid[N],fp[N];void dfs1(int u,int father,int d){ dep[u] = d; fa[u] = father; siz[u] = 1; for(int i=head[u];i!=-1;i=edge[i].nx) { int v = edge[i].to; if(v==father)continue; dfs1(v,u,d+1); siz[u] += siz[v]; if(son[u]==-1 || siz[v]>siz[son[u]]) son[u] = v; }}void dfs2(int u,int tp){ top[u] = tp; tid[u] = ++tot; fp[tot] = u; if(son[u]==-1)return; dfs2(son[u],tp); for(int i=head[u];i!=-1;i=edge[i].nx) { int v = edge[i].to; if(v==son[u] || v==fa[u])continue; dfs2(v,v); }}/*线段树*/struct node{ int col; int lc,rc,sum;}seg[N*4];void pushup(int rt){ seg[rt].sum = seg[rt<<1].sum + seg[rt<<1|1].sum; seg[rt].lc = seg[rt<<1].lc; seg[rt].rc = seg[rt<<1|1].rc; if(seg[rt<<1].rc == seg[rt<<1|1].lc) seg[rt].sum--;}void pushdown(int rt){ if(seg[rt].col) { seg[rt<<1].col = seg[rt<<1|1].col = 1; seg[rt].col = 0; seg[rt<<1].sum = seg[rt<<1|1].sum = 1; seg[rt<<1].lc = seg[rt<<1].rc = seg[rt].lc; seg[rt<<1|1].lc = seg[rt<<1|1].rc = seg[rt].rc; }}void build(int rt,int l,int r){ seg[rt].col = 0; if(l==r) { seg[rt].sum = 1; seg[rt].lc = seg[rt].rc = a[fp[r]]; //printf("%d\n",a[fp[l]]); return; } int mid = (l+r) >> 1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); pushup(rt);}void update(int rt,int l,int r,int L,int R,int c){ if(L<=l && r<=R) { seg[rt].col = 1; seg[rt].lc = seg[rt].rc = c; seg[rt].sum = 1; return; } pushdown(rt); int mid = (l+r) >> 1; if(L<=mid) update(rt<<1,l,mid,L,R,c); if(R>mid) update(rt<<1|1,mid+1,r,L,R,c); pushup(rt);}node query(int rt,int l,int r,int L,int R){ if(L<=l && r<=R) { return seg[rt]; } pushdown(rt); int mid = (l+r) >> 1; if(R<=mid) return query(rt<<1,l,mid,L,R); else if(L>mid) return query(rt<<1|1,mid+1,r,L,R); else { node p1 = query(rt<<1,l,mid,L,R); node p2 = query(rt<<1|1,mid+1,r,L,R); node res; res.sum = p1.sum + p2.sum; res.lc = p1.lc; res.rc = p2.rc; if(p1.rc==p2.lc) res.sum--; return res; }}void change(int x,int y,int z){ while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]])swap(x,y); update(1,1,n,tid[top[x]],tid[x],z); x = fa[top[x]]; } if(x==y) return; if(dep[x]<dep[y]) swap(x,y); update(1,1,n,tid[son[y]],tid[x],z);}int solve(int x,int y){ int ans = 0; int cx=-1,cy=-1; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) { swap(x,y);swap(cx,cy); } node tmp = query(1,1,n,tid[top[x]],tid[x]); ans += tmp.sum; if(tmp.rc==cx) ans--; cx = tmp.lc; x = fa[top[x]]; } if(x==y) { if(cx==cy)ans--; return ans; } if(dep[x]<dep[y]) { swap(x,y);swap(cx,cy); } node tmp = query(1,1,n,tid[son[y]],tid[x]); ans += tmp.sum; if(tmp.lc == cy) ans--; if(tmp.rc == cx) ans--; return ans;}char s[10];void init(){ memset(head,-1,sizeof head); memset(son,-1,sizeof son); cnt = 0; tot = 0;}int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);//ios::sync_with_stdio(0);//cin.tie(0);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,0); dfs2(1,1); for(int i=0;i<cnt;i+=2) { int x = edge[i].to; int y = edge[i].from; if(dep[x]<dep[y])swap(x,y); a[x] = edge[i].w; } build(1,1,n); while(m--) { scanf("%s",s); int a,b,c; if(s[0]=='Q') { scanf("%d%d",&a,&b); if(a==b)printf("0\n"); else { printf("%d\n",solve(a,b)); } } else { scanf("%d%d%d",&a,&b,&c); change(a,b,c); } } }return 0;}
0 0
- HDU5893 List wants to travel (树链剖分 + 线段树) 2016 ACM/ICPC Asia Regional Shenyang Online
- 模板【HDU5893 2016 ACM ICPC Asia Regional Shenyang Online B】【树链剖分 权在边上 链值合并 结构体写法】List wants to travel
- 2016 ACM/ICPC Asia Regional Shenyang Online HDU 5893 List wants to travel
- hdu5893 List wants to travel(树链剖分+线段树)
- hdu5893 List wants to travel(树链剖分+线段树)
- 2016 ACM/ICPC Asia Regional Shenyang Online
- 2016ACM/ICPC Shengyang Online-1002 List wants to travel
- 2015 ACM/ICPC Asia Regional Shenyang Online
- 2015 ACM/ICPC Asia Regional Shenyang Online
- 2015 ACM/ICPC Asia Regional Shenyang Online
- 2015 ACM/ICPC Asia Regional Shenyang Online
- 2015 ACM/ICPC Asia Regional Shenyang Online
- 2017 ACM/ICPC Asia Regional Shenyang Online
- 2017 ACM/ICPC Asia Regional Shenyang Online
- 2017 ACM/ICPC Asia Regional Shenyang Online
- 2017 ACM/ICPC Asia Regional Shenyang Online
- 2017 ACM/ICPC Asia Regional Shenyang Online
- 2017 ACM/ICPC Asia Regional Shenyang Online
- java泛型(三)、通配符的使用
- Android getevent/sendevent用法详解
- 如何实现RESTful Web API的身份验证
- IE6-IE9不支持table.innerHTML的解决方法
- Fresco使用详解
- HDU5893 List wants to travel (树链剖分 + 线段树) 2016 ACM/ICPC Asia Regional Shenyang Online
- 由加密文件引发的一个我无法解释的现象
- 随笔
- 零基础搭建nginx转码服务器
- 探秘Java中的String、StringBuilder以及StringBuffer
- 辞职后公积金和社保的注意事项
- servlet容器web服务器jsp引擎
- 使用配置文件连接数据库
- word-break:break-all和word-wrap:break-word的区别