2016 ACM/ICPC Asia Regional Shenyang Online HDU 5893 List wants to travel
来源:互联网 发布:尚品宅配怎么样 知乎 编辑:程序博客网 时间:2024/05/21 22:24
List wants to travel
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 331 Accepted Submission(s): 66
Problem Description
A boy named List who is perfect in English. Now he wants to travel and he is making a plan. But the cost of living in same citie always changes. Now he wants to know how many different kinds of continuous same cost he has to pay for living between two cities. Can you help him? (He is so lazy to do this by himself.)
Input
There are multiple cases. The first line contains two positive numbers N and M(N (N<=40000) where N is the amount of cities and M (M<=50000)) is the amount of operations.Then N-1 lines where each line have 3 integers a b and c, representing that there is a bidirectionoal road between city a and city b, and the cost is c.(a != b and c <= 100000). Then there are M lines of operation. For example, "Change a b c" means changing all the costs of the road which are passed by him when he travels from city a to city b to c. "Query a b" means he wants you to tell him how many different kinds of continuous same cost he has to pay traveling from city a to city b.(if a == b, the cost is 0).
Output
He insure you that there is exactly one route between every two different cities.
Sample Input
9 31 2 22 3 11 7 21 4 23 5 23 6 15 8 25 9 3Query 1 8Change 2 6 3Query 1 6
Sample Output
32
【题意】一颗无根树,两种操作:改变路径上的颜色,和询问路径上有多少段颜色。
【解题方法】算是bzoj原题了。。。bzoj 2243,不过bzoj上是点权,这里是边权,改一下就可以A了。这题之前写过,当时参考了这篇blog:http://blog.csdn.net/viphong/article/details/52167628
【具体分析】
原题是 点权,那么只需要查询时,判断当前链的顶端与链子的顶端的父亲是否同色即可。(或者判断链子的末端与last链的top是否同色),而现在是边权,则我们分开判断lca(u,v)对应的两条链即可即 。 int lastu=-1,col,lastv=-1;对于 查询一条 f1到u的链,求u的颜色 col=query_col(1,1,pos,p[u]);if (col==lastu) tmp--;最后u和v在一条链时,分别判断 u和lastu,v和lastv是否相等 (if u==v只判断一次即可)
【AC 代码】
////Created by just_sort 2016/9/12 17:37//Copyright (c) 2016 just_sort.All Rights Reserved//#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 100050;struct Edge{ int to,next,w; Edge(){} Edge(int a,int b,int c){to=a,next=b,w=c;}}edge[maxn*2],tmp[maxn];int head[maxn],tot,n,m,top[maxn],fa[maxn],dep[maxn],num[maxn],tid[maxn],son[maxn],tim;void init(){ tot = tim = 0; memset(head,-1,sizeof(head)); memset(son,-1,sizeof(son));}void addedge(int u,int v,int w){ edge[tot]={v,head[u],w}; head[u] = tot++;}void dfs1(int u,int pre,int d){ dep[u] = d; fa[u] = pre; num[u] = 1; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v != pre) { dfs1(v,u,d+1); num[u] += num[v]; if(son[u] == -1 || num[v] > num[son[u]]) son[u] = v; } }}void dfs2(int u,int tp){ top[u] = tp; tid[u] = ++tim; if(son[u]!=-1) dfs2(son[u],tp); for(int i = head[u] ; i != -1; i = edge[i].next) { int v = edge[i].to; if(v != son[u] && v != fa[u]) dfs2(v,v); }}struct SegmentTree{ int sum[4*maxn],add[4*maxn], numl[maxn*4], numr[maxn*4]; void init() { memset(sum,0,sizeof sum); memset(add,0,sizeof add); memset(numl,0,sizeof numl); memset(numr,0,sizeof numr); } void build(int l,int r,int rt) { add[rt] = -1; sum[rt] = 0; if(l==r) return; int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); } void pushUp(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]-(numr[rt<<1]==numl[rt<<1|1]); numl[rt]=numl[rt<<1]; numr[rt]=numr[rt<<1|1]; } void pushDown(int rt, int l, int r) { if(add[rt] != -1) { add[rt<<1]=add[rt<<1|1]=add[rt]; numl[rt<<1]=numl[rt<<1|1]=add[rt]; numr[rt<<1]=numr[rt<<1|1]=add[rt]; sum[rt<<1]=sum[rt<<1|1]=1; add[rt]=-1; } } void update(int rt, int l, int r, int L,int R, int c) { if(l > R || L > r) return ; if(l >=L && r <=R ) { sum[rt]=1; add[rt]=numl[rt]=numr[rt]=c; return ; } pushDown(rt, l, r); int mid = (l + r) >> 1; update(rt << 1, l, mid, L,R, c); update(rt << 1 | 1, mid + 1, r, L,R, c); pushUp(rt); } int query(int rt, int l, int r, int L, int R) { if(l > R || L > r) return 0; if(l >= L && r <= R) return sum[rt]; pushDown(rt, l, r); int m=(l+r)/2; int ret=0; if(L<=m) ret+=query(rt<<1,l,m,L,R); if(m<R) ret+=query(rt<<1|1,m+1,r,L,R); if(L<=m&&m<R) ret-=(numr[rt<<1]==numl[rt<<1|1]); return ret; } int querycol(int rt, int l, int r, int x) { if(l==r) return add[rt]; pushDown(rt, l, r); int m=(l+r)/2; if(x<=m) return querycol(rt<<1,l,m,x); return querycol(rt<<1|1,m+1,r,x); } int queryans(int u,int v) { int f1=top[u],f2=top[v]; int tmp=0; int cur; int lastu=-1,lastv=-1; while(f1!=f2) { if (dep[f1]<dep[f2]){ swap(f1,f2); swap(u,v); swap(lastu,lastv); } tmp+=query(1,1,tim,tid[f1],tid[u]); cur=querycol(1,1,tim,tid[u]); if (cur==lastu) tmp--; lastu=querycol(1,1,tim,tid[f1]); u=fa[f1],f1=top[u]; } if (u!=v) { if (dep[u]>dep[v] ) swap(u,v),swap(lastu,lastv); tmp+=query(1,1,tim,tid[son[u]],tid[v]); cur=querycol(1,1,tim,tid[v]); if (cur==lastv) tmp--; cur=querycol(1,1,tim,tid[son[u]]); if (cur==lastu) tmp--; } else if (lastu==lastv) tmp--; return tmp; } void negnate(int u,int v,int c) { int f1=top[u],f2=top[v]; while(f1!=f2) { if (dep[f1]<dep[f2]) { swap(f1,f2); swap(u,v); } update(1,1,tim,tid[f1],tid[u],c); u=fa[f1],f1=top[u]; } if (dep[u]>dep[v] ) swap(u,v); if (u!=v) update(1,1,tim,tid[son[u]],tid[v],c); }}tree;int main(){ int u,v,w; while(scanf("%d%d",&n,&m)!=EOF) { init(); tree.init(); for (int i=1; i<n; i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); tmp[i]=Edge(u,v,w); } dfs1(1,0,0); dfs2(1,1); tree.build(1,tim,1); for (int i=1; i<n; i++) { u=tmp[i].next,v=tmp[i].to,w=tmp[i].w; if (fa[u]==v) tree.update(1,1,tim,tid[u],tid[u],w); else tree.update(1,1,tim,tid[v],tid[v],w); } char op[10]; for (int i=1; i<=m; i++) { scanf("%s%d%d",op,&u,&v); if (op[0]=='Q'){ if(u==v) printf("0\n"); else printf("%d\n",tree.queryans(u,v)); } else{ scanf("%d",&w); tree.negnate(u,v,w); } } } return 0;}
0 0
- 2016 ACM/ICPC Asia Regional Shenyang Online HDU 5893 List wants to travel
- 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
- 2016ACM/ICPC Shengyang Online-1002 List wants to travel
- hdu 5451(2015 ACM/ICPC Asia Regional Shenyang Online)
- HDU 5458 Stability (2015 ACM/ICPC Asia Regional Shenyang Online)
- HDU-2017 ACM/ICPC Asia Regional Shenyang Online-签到题
- 2017 ACM/ICPC Asia Regional Shenyang Online 1001(hdu 6194)
- 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
- Android Studio 使用正式签名debug调试
- 三个重要的同余式——威尔逊定理、费马小定理、欧拉定理 + 求幂大法的证明
- 深度优先搜索【POJ 1979】
- 网教24. 波兰表达式
- 为什么不能用memcached存储Session
- 2016 ACM/ICPC Asia Regional Shenyang Online HDU 5893 List wants to travel
- Struts2实现验证码功能
- 【Android】Bitmap上绘制矩形/画中画
- URI跳转方式地图导航的代码实践 h5打开地图
- MySQL 5.7 的多源复制
- multi-agent 控制类论文阅读
- 海量数据处理利器greenplum——初识
- 4AppBarLayout滑动原理
- Velocity学习--如何判断一个对象是否为空(null)