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 ...
随机推荐
- Mysql执行大文件sql语句 -- 未测试
如果.sql文件过大,mysql会直接断开连接 解决方法: 在mysql的配置文件my.cnf 中加入 一行max_allowed_packet = 100M(该大小>=mysql.sql文件大 ...
- Js数组排序函数sort()
JS实现多维数组和对象数组排序,用的其实就是原生sort()函数,语法为:arrayObject.sort(sortby)(sortby 可选.规定排序顺序.必须是函数.) 返回值为对数组的引用:请注 ...
- 关于layui
之前用layer用了很长时间,感觉很好用,最近看到了layui的发布很想尝试尝试. 加入了挺多的功能,比如编辑器,上传,form表单等等.
- 当执行太多不受信任的代码时,除去令人讨厌的大量 trycatch 的办法
如果方法 Condition 返回 true,则执行 IfTrue,否则执行 IfFalse,发生异常则执行 IfError. 通常是这样: try { if (Condition()) { try ...
- svn快速教程
本文拷贝自网址:http://www.subversion.org.cn/?action-viewnews-itemid-1 如何快速建立Subversion服务器,并且在项目中使用起来,这是大家最关 ...
- 给libpcap增加一个新的捕包方法
libpcap是一个网络数据包捕获函数库,功能非常强大,提供了系统独立的用户级别网络数据包捕获接口,Libpcap可以在绝大多数类unix 平台下工作.大多数网络监控软件都以它为基础,著名的tcpdu ...
- Codeforces Round #373 (Div. 2) E. Sasha and Array
题目链接 分析:矩阵快速幂+线段树 斐波那契数列的计算是矩阵快速幂的模板题,这个也没什么很多好解释的,学了矩阵快速幂应该就知道的东西= =这道题比较巧妙的在于需要用线段树来维护矩阵,达到快速查询区间斐 ...
- 关于rem的学习
网页常见单位px.em.rem:其中rem是css3新出的单位,官网是这样定义的:“font size of the root element”,意思是:相对长度单位,相对于根元素(即html元素)f ...
- ASP.NETMVC自定义错误页面真的简单吗?
Note:文章前半部分翻译自 http://benfoster.io/blog/aspnet-mvc-custom-error-pages ,着急的可直接看总结~ 如果你在设置asp.net mvc自 ...
- 数位DP入门
HDU 2089 不要62 DESC: 问l, r范围内的没有4和相邻62的数有多少个. #include <stdio.h> #include <string.h> #inc ...