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 存储过程创建及执行简单实例
1. 创建 CREATE OR REPLACE PROCEDURE getAplage(eNo IN NUMBER,salary OUT NUMBER) AS BEGIN SELECT AplAge ...
- Jquery实现账单全部选中和部分选中管理
在做购物车系统是我们往往会遇到这样一个需求,在点击全选框时我们要将全部的单个账单都选中;在单个选中账单时,如果账单全部被选中则需要全选框处于选中状态,若没有全部被选中则全选框处于没选中状态; 以下是在 ...
- 与String有关的强制转换
String --> int int i = Integer.parseInteger("123"); String --> double double d = Dou ...
- selenium移动div里面的滚动条,操作弹出对话框
还是使用js来移动 首先要定位到这个元素 倾向于使用js来定位元素,输入下面的脚本,按下回车键,即可在调试页面看到对应的div块$("div.table-responsive") ...
- [HTML/HTML5]8 使用表格
8.1 创建基本的表格结构 8.1.1 表格结构 HTML表格包含4种基本元素: table:在HTML中table元素是一个容器,其中包含用于创建表格的其它的元素: tr:表示表格中的行,开始标 ...
- C++对于大型图片的加载缩放尝试
Qt对于图片的操作主要集中在这几个类 QImage ,QImageReader ,QPixmap 其中QImage这个类对图片的缩放有几个很不错的技巧,不过对于大图片却并不好使,当我们去看QImage ...
- Maven学习链接
别人的资料很多且写的很详细,我这里先收藏,等学习到一定阶段且有时间再整理自己的积累. 1.eclipse安装maven插件方法: http://blog.csdn.net/kittyboy0001/a ...
- JS学习笔记--仿手机发送内容交互
学习JS笔记----记录上课中学习的知识点,分享下老师教的内容: 1.html内容 <div id="box"> <div id="message&qu ...
- System.Data.Oracleclient需要Oracle客户端软件Version8.1.7或更高版本问题
C#连接ORACLE报System.Data.Oracleclient需要Oracle客户端软件Version8.1.7或更高版本问题: 开始Webservice在32位系统ORACLE10g库中we ...
- sql sever跨数据库复制数据的方法【转】
1,用Opendatasource系统函数 详细的用法已经注释在sql代码中了.这个是在sqlserver到sqlserver之间的倒数据.2005,2008,2012应该都是适用的. --从远程服务 ...