洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)
【思路】:
涉及到树上区间修改操作,所以使用树链剖分,涉及到区间查询,所以使用线段树。
update操作时,就正常操作,难点在于query操作的计数。
因为树链剖分的dfs序只能保证一条重链上的dfn[]连续,不能使得任意两点之间简单路径上的dfn[]连续,所以当x往上跳到fa[top[x]]时,要判断
top[x]的颜色与fa[top[x]]的颜色是否相同,如果相同要再减一。
以及在线段树中query操作和pushUp时,都要判断左儿子的右端点与右儿子的左端点是否相同,如果在pushUp中相同,则令此时的segtree[id]减一,
如果在query中相同,那么使得query函数返回的结果减一。 接下来上代码。
#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + ;
int n, m, a[maxn];
int segtree[maxn<<], lazy[maxn<<], lft[maxn<<], rht[maxn<<];
int head[maxn], tot, cnt;
int fa[maxn], top[maxn], dfn[maxn], rk[maxn], siz[maxn], dep[maxn], son[maxn];
struct edge{
int to,next;
} ed[maxn<<];
inline int read(){
int k=, f=;
char ch=getchar();
while( ch>'' || ch<'' ){ if(ch=='-') f=-; ch=getchar(); }
while( ch>='' && ch<='' ){ k=k*+ch-''; ch=getchar(); }
return k*f;
} inline void init(){
memset( head ,-, sizeof(head) );
memset( lazy, -, sizeof(lazy) );
tot = ;
} inline void add( int u, int v ){
ed[++tot].to = v; ed[tot].next = head[u]; head[u] = tot;
ed[++tot].to = u; ed[tot].next = head[v]; head[v] = tot;
} inline void dfs1( int x ){
siz[x] = ;
for( int i=head[x]; ~i; i=ed[i].next ){
int y = ed[i].to;
if( y==fa[x] ) continue;
dep[y] = dep[x]+;
fa[y] = x;
dfs1(y);
siz[x] += siz[y];
if( son[x]== || siz[y]>siz[son[x]] ) son[x] = y;
}
} inline void dfs2( int x, int tp ){
top[x] = tp;
dfn[x] = ++cnt;
rk[cnt] = x;
if( son[x] ) dfs2( son[x], tp );
for( int i=head[x]; ~i; i=ed[i].next ){
int y = ed[i].to;
if( y!=fa[x] && y!=son[x] ) dfs2(y, y);
}
} inline void pushUp( int id ){
segtree[id] = segtree[id<<] + segtree[id<<|];
if( lft[id<<|]==rht[id<<] ) segtree[id] --;
lft[id] = lft[id<<]; rht[id] = rht[id<<|];
} inline void pushDown( int id ){
if( lazy[id]==- ) return;
lazy[id<<] = lazy[id<<|] = lazy[id];
segtree[id<<] = segtree[id<<|] = ;
lft[id<<] = lft[id<<|] = rht[id<<] = rht[id<<|] = lazy[id];
lazy[id] = -;
} inline void build( int l, int r, int id ){
if( l==r ){
lft[id] = rht[id] = a[rk[l]];
segtree[id] = ;
return ;
}
int mid=l+r>>;
build( l, mid, id<< );
build( mid+, r, id<<| );
pushUp(id);
} inline void update_tree( int l, int r, int ql, int qr, int id, int c ){
if( ql<=l && qr>=r ){
segtree[id] = ;
lft[id] = rht[id] = c;
lazy[id] = c;
return ;
}
pushDown(id);
int mid = l+r>>;
if( ql<=mid ) update_tree( l, mid, ql, qr, id<<, c );
if( qr>mid ) update_tree( mid+, r, ql, qr, id<<|, c );
pushUp(id);
} inline int query( int l, int r, int ql, int qr, int id ){
if( ql<=l && qr>=r ) return segtree[id];
pushDown(id);
int mid = l+r>>;
int res = ;
if( ql<=mid ) res += query( l, mid, ql, qr, id<< );
if( qr>mid ) res += query( mid+, r, ql, qr, id<<| );
if( ql<=mid && qr>mid && lft[id<<|]==rht[id<<] ) res--; //这里也要判断一次是否相同,前提是要跨立区间
return res;
} inline int color_query( int l, int r, int idx, int id ){
if( l==r ) return lft[id];
pushDown(id);
int mid = l+r>>;
if( idx<=mid ) return color_query( l, mid, idx, id<< );
else return color_query( mid+, r, idx, id<<| );
} inline void swap( int &x, int &y ){ x^=y^=x^=y; } inline int sum( int x, int y ){
int res = ;
while( top[x]!=top[y] ){
if( dep[top[x]]<dep[top[y]] ) swap(x, y);
res += query(, n, dfn[top[x]], dfn[x], );
if( color_query(, n, dfn[top[x]], )==color_query(, n, dfn[fa[top[x]]], ) ) res --; //颜色相同减一
x = fa[top[x]];
}
if( dfn[x]>dfn[y] ) swap(x, y);
res += query( , n, dfn[x], dfn[y], );
return res== ? :res;
} inline void update_chain( int x, int y, int c ){
while( top[x]!=top[y] ){
if( dep[top[x]]<dep[top[y]] ) swap(x, y);
update_tree(, n, dfn[top[x]], dfn[x], , c );
x = fa[top[x]];
}
if( dfn[x]>dfn[y] ) swap(x, y);
update_tree( , n, dfn[x], dfn[y], , c );
} int main(){
// freopen("in.txt", "r", stdin);
init();
n = read(); m = read();
for( int i=; i<=n; i++ ) a[i] = read();
for( int i=; i<n; i++ ){
int u=read(), v=read();
add(u, v);
}
dep[] = fa[] = ;
dfs1();
dfs2(, );
build( , n, );
char ch[];
while( m-- ){
int x, y, z;
scanf("%s", ch);
x = read(); y = read();
if( ch[]=='Q' ) printf("%d\n", sum(x, y));
else{
z = read();
update_chain(x, y, z);
}
} return ;
}
洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)的更多相关文章
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 2243: [SDOI2011]染色 树链剖分+线段树染色
给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
随机推荐
- appium--Toast元素识别
前戏 Android中的Toast是一种简易的消息提示框,当视图显示给用户,在应用程序中显示为浮动,和Dialog不一样的是,它永远不会获得焦点,无法被点击 Toast类的思想就是尽可能不引人注意,同 ...
- js中VO解析
执行环境(环境) 执行环境的用处 执行环境定义了变量或函数有权访问的其他数据,每一个执行环境都存在一个关联的变量对象(VO),代码无法访问,内部解析器会使用它,如果环境为函数,则将函数的AO作为VO, ...
- CPU、内存、磁盘的瓶颈(转载文)
1.如何判断CPU.内存.磁盘的瓶颈? CPU瓶颈1) 查看CPU利用率.建议CPU指标如下 a) User Time:65%-70% b) System Time:30%-35% c) Idle:0 ...
- oracle--10GRAC集群(NFS共享存储)
一,NFS服务器配置 01, 安装包查看 [root@standby2 ~]# rpm -qa|grep nfs nfs-utils-lib--.el6.x86_64 nfs4-acl-tools-- ...
- Tomcat启用HTTPS协议配置过程
Article1较为简洁,Article2较为详细,测试可行. Article1 概念简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问 ...
- 批量插入sql技巧
方式一: ); ); 方式二: ), (); 第二种比较好.第二种的SQL执行效率高的主要原因是合并后日志量(MySQL的binlog和innodb的事务让日志)减少了,降低日志刷盘的数据量和频率,从 ...
- 通过四个问题了解HTTP协议基础
很多人都知道学习和理解HTTP协议的重要性及必要性,但HTTP相关知识对计算机基础较差,尤其是我这种没有计算机基础的人来说更是晦涩难懂 乘着最近有空闲时间,开始恶补HTTP相关基础知识,下面请跟着我通 ...
- Android 支持库迁移到AndroidX
一.背景 Android系统版本在不断更新,从最初的Android 1.0到现在Google和各大手机厂商正在推的Android 10,平均下来每个年头都有一个大的版本更新.但用户正在用的手机上的An ...
- Redis-2-五种基本类型及相关命令
目录 1.字符串类型:string 1.1 命令 1.2 实践 2.散列类型:hash 2.1命令 2.2 实践 3.列表类型:list 3.1 命令 3.2 实践 4.集合类型:set 4.1 命令 ...
- java 获取真实ip地址
/** * 获取真实ip地址 * @param request * @return */ public static String getIpAddress(HttpServletRequest re ...