#include<bits/stdc++.h>
using namespace std;
const int M=3e5+;
struct node{
int l,r,cnt,lazy;
node(int l1=,int r1=,int cnt1=,int lazy1=):l(l1),r(r1),cnt(cnt1),lazy(lazy1){}
}tree[M<<];
int fa[M],sz[M],deep[M],dfn[M],son[M],to[M],a[M],top[M],cnt,n;
char s[];
vector<int>g[M];
void dfs1(int u,int from){
fa[u]=from;
sz[u]=;
deep[u]=deep[from]+;
for(int i=;i<g[u].size();i++){ int v=g[u][i];
if(v!=from){
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]])
son[u]=v;
} }
}
void dfs2(int u,int t){
top[u]=t;
dfn[u]=++cnt;
to[cnt]=u;
if(!son[u])
return ;
dfs2(son[u],t);
for(int i=;i<g[u].size();i++){
int v=g[u][i];
if(v!=fa[u]&&v!=son[u])
dfs2(v,v);
}
}
void up(int root){
tree[root].cnt=tree[root<<].cnt+tree[root<<|].cnt;
if(tree[root<<].r==tree[root<<|].l)
tree[root].cnt--;
tree[root].l=tree[root<<].l;
tree[root].r=tree[root<<|].r;
}
void build(int root,int l,int r){
tree[root].lazy=;
if(l==r){
tree[root].l=tree[root].r=a[to[l]];
tree[root].cnt=;
return ;
}
int midd=(l+r)>>;
build(root<<,l,midd);
build(root<<|,midd+,r);
up(root);
}
void pushdown(int root){
tree[root<<]=tree[root<<|]=node(tree[root].l,tree[root].r,,tree[root].lazy);
tree[root].lazy=;
}
void update(int L,int R,int x,int root,int l,int r){
if(L<=l&&r<=R){
tree[root]=node(x,x,,x);
return ;
}
if(tree[root].lazy)
pushdown(root);
int midd=(l+r)>>;
if(L<=midd)
update(L,R,x,root<<,l,midd);
if(R>midd)
update(L,R,x,root<<|,midd+,r);
up(root);
}
void add(int u,int v ,int w){
int fu=top[u],fv=top[v];
while(fu!=fv){
if(deep[fu]>=deep[fv])
update(dfn[fu],dfn[u],w,,,n),u=fa[fu],fu=top[u];
else
update(dfn[fv],dfn[v],w,,,n),v=fa[fv],fv=top[v];
}
if(dfn[u]<=dfn[v])
update(dfn[u],dfn[v],w,,,n);
else
update(dfn[v],dfn[u],w,,,n);
}
node meger(node a,node b){
if(!a.cnt)
return b;
if(!b.cnt)
return a;
node ans=node(,,,);
ans.cnt=a.cnt+b.cnt;
if(a.r==b.l)
ans.cnt--;
ans.l=a.l;
ans.r=b.r;
return ans;
}
node query(int L,int R,int root,int l,int r){
if(L<=l&&r<=R){
return tree[root];
}
if(tree[root].lazy)
pushdown(root);
int midd=(l+r)>>;
node ans;
if(L<=midd)
ans=query(L,R,root<<,l,midd);
if(R>midd)
ans=meger(ans,query(L,R,root<<|,midd+,r));
up(root);
return ans;
}
int solve(int u,int v){
node l,r;
int fv=top[v],fu=top[u];
while(fv!=fu){
if(deep[fu]>=deep[fv])
l=meger(query(dfn[fu],dfn[u],,,n),l),u=fa[fu],fu=top[u];
else
r=meger(query(dfn[fv],dfn[v],,,n),r),v=fa[fv],fv=top[v];
}
if(dfn[u]<=dfn[v])
r=meger(query(dfn[u],dfn[v],,,n),r);
else
l=meger(query(dfn[v],dfn[u],,,n),l);
swap(l.l,l.r);
l=meger(l,r);
return l.cnt;
}
int main(){
int m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}//cout<<"!!"<<endl;
dfs1(,);
dfs2(,); build(,,n);
while(m--){
int u,v,w;
scanf("%s",s);
if(s[]=='Q'){
scanf("%d%d",&u,&v);
printf("%d\n",solve(u,v));
}
else{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
}
return ;
}

P2486 [SDOI2011]染色 区间合并+树链剖分(加深对线段树的理解)的更多相关文章

  1. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  2. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

  3. HDU 5029 Relief grain 树链剖分打标记 线段树区间最大值

    Relief grain Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  4. LOJ2269 [SDOI2017] 切树游戏 【FWT】【动态DP】【树链剖分】【线段树】

    题目分析: 好题.本来是一道好的非套路题,但是不凑巧的是当年有一位国家集训队员正好介绍了这个算法. 首先考虑静态的情况.这个的DP方程非常容易写出来. 接着可以注意到对于异或结果的计数可以看成一个FW ...

  5. [GDOI2016] 疯狂动物园 [树链剖分+可持久化线段树]

    题面 太长了,而且解释的不清楚,我来给个简化版的题意: 给定一棵$n$个点的数,每个点有点权,你需要实现以下$m$个操作 操作1,把$x$到$y$的路径上的所有点的权值都加上$delta$,并且更新一 ...

  6. HYSBZ 4034 【树链剖分】+【线段树 】

    <题目链接> 题目大意: 有一棵点数为 N 的树,以点 1 为根,且树点有权值.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...

  7. HDU 3966 Aragorn's Story(模板题)【树链剖分】+【线段树】

    <题目链接> 题目大意: 给定一颗带点权的树,进行两种操作,一是给定树上一段路径,对其上每个点的点权增加或者减少一个数,二是对某个编号点的点权进行查询. 解题分析: 树链剖分的模板题,还不 ...

  8. 焦作网络赛E-JiuYuanWantstoEat【树链剖分】【线段树】

    You ye Jiu yuan is the daughter of the Great GOD Emancipator. And when she becomes an adult, she wil ...

  9. 【树链剖分】【线段树】bzoj3626 [LNOI2014]LCA

    引用题解: http://blog.csdn.net/popoqqq/article/details/38823457 题目大意: 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深 ...

  10. 【Codeforces】【网络流】【树链剖分】【线段树】ALT (CodeForces - 786E)

    题意 现在有m个人,每一个人都特别喜欢狗.另外还有一棵n个节点的树. 现在每个人都想要从树上的某个节点走到另外一个节点,且满足要么这个人自带一条狗m,要么他经过的所有边h上都有一条狗. 2<=n ...

随机推荐

  1. redis(二)----基本操作

    1. redis介绍 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset( ...

  2. 18 12 25 css 基本语法以及页面使用

    css的定义方法是: 选择器 { 属性:值; 属性:值; 属性:值;} 选择器是将样式和页面元素关联起来的名称,属性是希望设置的样式属性每个属性有一个或多个值 css页面引入方法: 1.外联式:通过l ...

  3. Fedora、SuSE、Redhat、Ubuntu、Centos

    想学Linux,但版本太多了,如Fedora.SuSE.Redhat.Ubuntu等,不免让人眼花缭乱,那么初学者该如何选择呢?也许很多人会不屑的说,Linux不就是个操作系统么.错!Linux不是一 ...

  4. 学生信息的添加 Java web简单项目初试(失败)

    题目要求: 1登录账号:要求由6到12位字母.数字.下划线组成,只有字母可以开头:(1分) 2登录密码:要求显示“• ”或“*”表示输入位数,密码要求八位以上字母.数字组成.(1分) 3性别:要求用单 ...

  5. PL/SQL 连接oracle步骤

    下面就将PL/SQL的配置说明一下. 一.安装Oracle客户端,让后配置    安装目录下面的C:\ORACLE\instantclient_11_2\NETWORK\ADMIN 的 tnsname ...

  6. eclipse maven配置问题:org.apache.maven.archiver.mavenarchiver.getmanifest

    原因就是你的maven的配置文件不是最新的 1.help ->Install New Software -> add ->https://otto.takari.io/content ...

  7. JavaScript中的深浅拷贝

    深浅拷贝 在JS中,数据类型分为两类: ​ 简单数据类型:Number.Boolean.String.undefined ​ 引用数据类型:Array.Object.Function 简单数据类型通常 ...

  8. mysql数据库大规模数据读写并行时导致的锁表问题

    问题介绍 最近在给学校做的一个项目中,有一个功能涉及到考核分数问题. 我当时一想,这个问题并不是很难,于是就直接采用了这样的方法:拿着一个表中的数据作为索引,去挨个遍历相关表中的数据,最后经过算分的过 ...

  9. JZOJ-TG817-A-solution

    T1 考虑是否有一种排序方法使得最优解都相邻,这种排序方法就是按照过一个点x的斜率为(P/Q)的直线的截距 排序之后考虑临项即可,O(N) T2 exit

  10. django2:路由path语法

    目录 1.问题引入 2.使用示例 3.path转化器 4.自定义转化器 4.1 定义 4.2 注册 5.使用正则表达式 6.Import变动 7.代码改写 8.总结 9月23,Django 发布了2. ...