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 ...
随机推荐
- How to Make Terrains in Tiled Map Editor
Published July 13th, 2015 by Stephen Gygi How to Make Terrains in Tiled Map Editor http://www.binary ...
- node与mongodb的使用
1.mongdb安装好后,在.bin文件夹下执行mongod.exe --dbpath=D:\mongodb\db 即可启动mongodb,表示将数据放在db这个文件夹,且每一次启动要执行完整的这句 ...
- Leetcode--Swap Nodes in Pairs
最傻的方法: ListNode *swapPairs(ListNode *head) { if (head == NULL) return NULL; ListNode *temp = ); List ...
- nodejs解决找不到express命令的问题
一般的书或者教程上的安装步骤是:(需要是-g,即全局安装) npm install -g express //全局安装 而我们应该多多关注下express的文档,github地址:https://gi ...
- (转抄:人人都是产品经理——iamsujie)如何提高产品规划PPT的能力
做产品几年之后,不可避免的要碰到写规划这件事儿,虽说不少人,不乏大牛,对规划持“无用论”的观点, 但大多数人其实还是更相信这个段子: 在一个公司里,看一个人的地位,主要看他平时写的文档类型——写wor ...
- gulp教程之gulp-uglify
简介: 使用gulp-uglify压缩javascript文件,减小文件大小. 1.安装nodejs/全局安装gulp/项目安装gulp/创建package.json和gulpfile.js文件 1. ...
- Javascript学习笔记2.1 Javascript与DOM简介
DOM(文档对象模型)简介 DOM(文档对象模型)针对HTML和XML文档的一个API. DOM可以将任何HTML或XML文档描绘成由多层节点构成的树形结构,它是中立于平台和语言的接口,允许程序和脚本 ...
- css学习归纳总结(一) 转
原文地址:CSS学习归纳总结(一) 选择器的分组 CSS选择器分为 1.群组选择器 如:p, body, img, div{} 2.兄弟选择器 如:p + p { color:#f00; } 3.属性 ...
- MVC5 + EF6 完整入门教程三:EF来了
期待已久的EF终于来了 学完本篇文章,你将会掌握基于EF数据模型的完整开发流程. 本次将会完成EF数据模型的搭建和使用. 基于这个模型,将之前的示例添加数据库查询验证功能. 文章提纲 概述 & ...
- 关于在终端运行rosrun时找不到对应的包的解决方法
输入命令:rosrun kinect2_bridge kinect2_bridge 错误如下:[rospack] Error: package 'kinect2_bridge' not found 解 ...