HYSBZ 2243
//Accepted 18440 KB 5556 ms /* source:HYSBZ 2243 time :2015.5.29 by :songt */ /*题解: 树链剖分 */ #include <cstdio> #include <cstring> ; struct Edge { int u,v; Edge(){} Edge(int u,int v):u(u),v(v){} }edge[*imax_n]; int head[imax_n]; *imax_n]; int tot; int top[imax_n]; int son[imax_n]; int num[imax_n]; int p[imax_n]; int fp[imax_n]; int deep[imax_n]; int fa[imax_n]; int pos; void init() { memset(head,-,sizeof(head)); memset(next,-,sizeof(next)); tot=; memset(son,-,sizeof(son)); pos=; } void addEdge(int u,int v) { edge[tot]=Edge(u,v); next[tot]=head[u]; head[u]=tot++; } void dfs1(int u) { num[u]=; ;i=next[i]) { int v=edge[i].v; if (v!=fa[u]) { fa[v]=u; deep[v]=deep[u]+; dfs1(v); num[u]+=num[v]; || num[son[u]]<num[v]) son[u]=v; } } } void dfs2(int u) { p[u]=pos++; fp[p[u]]=u; ) return ; top[son[u]]=top[u]; dfs2(son[u]); ;i=next[i]) { int v=edge[i].v; if (v!=son[u] && v!=fa[u]) { dfs2(top[v]=v); } } } struct Tree { int l,r; int lc,rc; int num; int same; int color; }f[imax_n*]; int color[imax_n]; void push_down(int t) { f[*t].same=f[*t+].same=; f[*t].color=f[*t+].color=f[t].color; f[*t].num=f[*t+].num=; f[*t].lc=f[*t].rc=f[t].color; f[*t+].lc=f[*t+].rc=f[t].color; f[t].same=; } void push_up(int t) { f[t].num=f[*t].num+f[*t+].num-(f[*t].rc==f[*t+].lc); f[t].lc=f[*t].lc; f[t].rc=f[*t+].rc; } void build(int t,int l,int r) { f[t].l=l; f[t].r=r; f[t].same=; if (l==r) { f[t].lc=f[t].rc=color[fp[l]]; f[t].color=color[fp[l]]; f[t].num=; f[t].same=; return ; } ; build(*t,l,mid); build(*t+,mid+,r); push_up(t); } void update(int t,int l,int r,int color) { if (f[t].l==l && f[t].r==r) { f[t].color=color; f[t].num=; f[t].lc=f[t].rc=color; f[t].same=; return ; } if (f[t].same) push_down(t); ; *t,l,r,color); else { *t+,l,r,color); else { update(*t,l,mid,color); update(*t+,mid+,r,color); } } push_up(t); } int query(int t,int l,int r,int &cl,int &rl) { if (f[t].l==l && f[t].r==r) { cl=f[t].lc; rl=f[t].rc; return f[t].num; } if (f[t].same) push_down(t); ; *t,l,r,cl,rl); else { *t+,l,r,cl,rl); else { int lcl,lcr,rcl,rcr; int numl,numr; numl=query(*t,l,mid,lcl,lcr); numr=query(*t+,mid+,r,rcl,rcr); cl=lcl; rl=rcr; return numl+numr-(lcr==rcl); } } } void swap(int &a,int &b) { int t=a; a=b; b=t; } void OpC(int u,int v,int c) { int f1=top[u],f2=top[v]; while (f1!=f2) { //printf("u=%d v=%d top[u]=%d top[v]=%d\n",u,v,f1,f2); if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } update(,p[f1],p[u],c); //printf("update %d %d\n",f1,u); u=fa[f1]; f1=top[u]; } if (deep[u]>deep[v]) swap(u,v); update(,p[u],p[v],c); //printf("update %d %d\n",u,v); } int OpQ(int u,int v) { int f1=top[u],f2=top[v]; ,cv=-; ; int lc,rc; while (f1!=f2) { if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); swap(cu,cv); } ,p[f1],p[u],lc,rc); //printf("%d %d num=%d lc=%d rc=%d\n",f1,u,tmp,lc,rc); ans+=tmp; ans-=(cu==rc); cu=lc; u=fa[f1]; f1=top[u]; } if (deep[u]>deep[v]) { swap(u,v); swap(cu,cv); } ,p[u],p[v],lc,rc); //printf("%d %d num=%d lc=%d rc=%d\n",u,v,tmp,lc,rc); ans+=query(,p[u],p[v],lc,rc); ans-=(cu==lc); ans-=(cv==rc); return ans; } int n,m; ]; int u,v,c; int main() { //while (scanf("%d%d",&n,&m)==2) scanf("%d%d",&n,&m); { init(); ;i<=n;i++) { scanf("%d",&color[i]); } ;i<n-;i++) { scanf("%d%d",&u,&v); addEdge(u,v); addEdge(v,u); } fa[]=; deep[]=; dfs1(); dfs2(top[]=); build(,,pos-); ;i<m;i++) { scanf("%s",op); ]=='Q') { scanf("%d%d",&u,&v); printf("%d\n",OpQ(u,v)); } else { scanf("%d%d%d",&u,&v,&c); OpC(u,v,c); } } } ; }
HYSBZ 2243的更多相关文章
- HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- HDU 3966 & POJ 3237 & HYSBZ 2243 & HRBUST 2064 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- hysbz 2243 染色(树链剖分)
题目链接:hysbz 2243 染色 题目大意:略. 解题思路:树链剖分+线段树的区间合并,可是区间合并比較简单,节点仅仅要记录左右端点的颜色就可以. #include <cstdio> ...
- HYSBZ 2243(树链剖分)
题目连接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/D 题意:给定一棵有n个节点的无根树及点权和m个操作, ...
- HYSBZ 2243 染色 (树链拆分)
主题链接~~> 做题情绪:这题思路好想.调试代码调试了好久.第一次写线段树区间合并. 解题思路: 树链剖分 + 线段树区间合并 线段树的端点记录左右区间的颜色.颜色数目.合并的时候就用区间合并的 ...
- HYSBZ 2243(染色)
题目链接:传送门 题目大意:中文题,略 题目思路:树链剖分,区间更新,区间查询. 闲谈: 只想说这道题做的好苦逼..去长春现场赛之前就没A,回来后又做了2天才A掉,蒟蒻太菜了 这道题也没有想 ...
- HYSBZ - 2243 染色 (树链剖分+线段树)
题意:树上每个结点有自己的颜色,支持两种操作:1.将u到v路径上的点颜色修改为c; 2.求u到v路径上有多少段不同的颜色. 分析:树剖之后用线段树维护区间颜色段数.区间查询区间修改.线段树结点中维护的 ...
- HYSBZ - 2243 树链剖分 + 线段树 处理树上颜色段数
用线段树处理颜色段数 记录区间内的颜色段数,区间右端点的颜色,区间右端点的颜色. int tr[maxn<<2], lc[maxn<<2], rc[maxn<<2] ...
- HYSBZ 2038 莫队算法
小Z的袜子(hose) Time Limit:20000MS Memory Limit:265216KB 64bit IO Format:%lld & %llu Submit ...
随机推荐
- 多线程学习中的Tips
ParameterizedThreadStart委托与ThreadStart委托,非常相似,但ParameterizedThreadStart委托是面向带参数方法的.注意ParameterizedTh ...
- 哈希表(Hash Table)
参考: Hash table - Wiki Hash table_百度百科 从头到尾彻底解析Hash表算法 谈谈 Hash Table 我们身边的哈希,最常见的就是perl和python里面的字典了, ...
- OneProxy自动剔除延迟节点
在多种情况下,MySQL主从节点之间可能存在延迟.比如,主库的写入能力强于从库的写入能力.从库单线程复制.从库复制出错导致相关进程停止.为了保证数据的时效性,OneProxy提供了复制时效性检查,用于 ...
- python编程(一)汉诺塔
题目描述 编写move(n, a, b, c)函数,它接收参数n,表示3个柱子A.B.C中第1个柱子A的盘子数量,然后打印出把所有盘子从A借助B移动到C的方法. 例: move(3, 'A', 'B' ...
- Spring mvc Controller接口
Spring MVC 1. 继承该接口 Controller接口,重写对应方法,或者采用注解Controller,自定义映射文件 @Controller @RequestMapping("/ ...
- 渐变算法的 Java 实现
/** * 指定长度的渐变. * @param c0 起始颜色. * @param c1 结束颜色. * @param len 受限的渐变长度,为保证每一个颜色都不一样,会根据颜色找出长度最大值. * ...
- vue.common.js?e881:433 TypeError: Cannot read property 'nodeName' of undefined
我觉得吧,是这么个原因,就是响应式要找这个node改它的内容,没找着,就报错了. 用computed监控vuex的state属性,绑定到页面上,如果这个属性改了,因为响应式,那么就要更改页面,如果页面 ...
- UITableView UITableViewCell
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- Node与express开发
1.初识Express Express 网站上是这样介绍 Express 的: "精简的.灵活的 Node.js Web 程序框架,为构建单页.多页及混合的 Web 程序提供了一系列健壮的功 ...
- 自制c#简易计算器
这是一个课堂作业,我觉得作为一个简易的计算器不需要态度复杂的东西,可能还有一些bug,有空再慢慢加强. using System;using System.Collections.Generic;us ...