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 ...
随机推荐
- 【oracle】 oracle学习笔记1--安装与登录
由于机器配置原因,加上也是自学,所以就没必要安装专业版的oracle,于是就安装的oracle xe版本 下载地址:http://www.oracle.com/technetwork/database ...
- 前台jquery+ajax+json传值,后台处理完后返回json字符串,如何取里面的属性值?(不用springmvc注解)
一.取属性值 前台页面: function select(id){ alert("hfdfhdfh"+id); $.ajax({ url:"selectByid.jsp& ...
- 几款极好的 JavaScript 文件上传插件
文件上传功能作为网页重要的组成部分,几乎无处不在,从简单的单个文件上传到复杂的批量上传.拖放上传,需要开发者花费大量的时间和精力去处理,以期实现好用的上传功能.这篇文章向大家推荐几款很棒的 JavaS ...
- 使用requestAnimationFrame做动画效果二
3月是个好日子,渐渐地开始忙起来了,我做事还是不够细心,加上感冒,没精神,今天差点又出事了,做过的事情还是要检查一遍才行,哎呀. 使用requestAnimationFrame做动画,我做了很久,终于 ...
- Nodejs express中创建ejs项目,解决express下默认创建jade,无法创建ejs问题
最近在看<Node.js开发指南>,看到使用nodejs进行web开发的时候,准备创建ejs项目遇到问题了, 书上命令为: express -t ejs microblog 可是执行后,仍 ...
- 四种主要网络IO虚拟化模型
本文主要为大家简要介绍VMware.Redhat.Citrix.Microsoft主要虚拟化厂商使用的4种主要的虚拟化IO模型 (emulation.para-virtualization.pass- ...
- Java中如何克隆集合——ArrayList和HashSet深拷贝
编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法.需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味 ...
- 前端常用的几个js判断(一)
1. 禁止右键点击$(document).ready(function(){ $(document).bind("contextmenu",function(e){ return ...
- css属性的书写
书写顺序: 注释方式: /* 块状注释文字 * 块状注释文字 * 块状注释文字 */ .m-list{width:500px;} .m-list li{height:20px;line-height: ...
- java selenium (十二) 操作弹出窗口
selenium 中如何处理弹出窗口 阅读目录 原理 在代码里, 通过 Set<String> allWindowsId = driver.getWindowHandles ...