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 ...
随机推荐
- 《开源大数据分析引擎Impala实战》目录
当当网图书信息: http://product.dangdang.com/23648533.html <开源大数据分析引擎Impala实战>目录 第1章 Impala概述.安装与配置.. ...
- asp.net用户自定义控件传参
asp.net自定义控件传参的方式有2中: ①字段的方式 在自定义控件的.ascx.cs中定义一个字段,然后在调用页面的page_load方法里面传入参数. 如 在自定义控件中设置字段 publ ...
- Android中View类OnClickListener和DialogInterface类OnClickListener冲突解决办法
Android中View类OnClickListener和DialogInterface类OnClickListener冲突解决办法 如下面所示,同时导入这两个,会提示其中一个与另一个产生冲突. 1i ...
- Window通过cmd查看端口占用、相应进程、杀死进程
在windows下启动程序时候经常出现端口占用, 修改本程序端口是一种解决思路,但是更多时候希望直接杀掉占用端口的程序: 一. 查看所有进程占用的端口 在开始-运行-cmd,输入: netsta ...
- android studio gradle结构项目引入本地代码
1.首先需要用eclipse打开目标项目,file export,选择gradle file. 2.拷贝文件到as项目的根目录[可选] 3.找到as项目的根目录下 .idea目录,下面有个module ...
- Windows 2008 R2+iis7.5环境下Discuz!X3论坛伪静态设置方法
2008R2不是那么的普及,加上X3版新出不久,所以伪静态的设置教程比较少,今天搞出来了,其实很简单,那么下面给大家简要说明一下.因为iis7.5集成了url重写,那就就方便多了,首先安装好你的dz论 ...
- TransactionScope oracle不能用的问题(转载)
报错:“无法加载oramts.dll ”的错误 参见文章:关于TransactionScope分布式事务在Oracle下的运作
- python 异常处理、文件常用操作
异常处理 http://www.jb51.net/article/95033.htm 文件常用操作 http://www.jb51.net/article/92946.htm
- 企业项目开发--分布式缓存Redis
第九章 企业项目开发--分布式缓存Redis(1) 注意:本章代码将会建立在上一章的代码基础上,上一章链接<第八章 企业项目开发--分布式缓存memcached> 1.为什么用Redis ...
- Windows Store App JavaScript 开发:WinJS库控件
在介绍了如何使用标准的HTML控件以及WinJS库中提供的新控件之后,下面来着重介绍WinJS库中几种常用的控件. (1)ListView控件 在开发Windows应用商店应用时可以使用ListVie ...