正解:线段树+树链剖分

解题报告:

传送门$QwQ$

其实是道蛮板子的题,,,但因为我写得很呆然后写了贼久之后发现想法有问题要重构,就很难受,就先写个题解算了$kk$

考虑先跑个树剖,然后按$dfn$序建线段树,区间修改区间查询就行

然后唯一要注意细节的点就因为它是查询颜色段,所以当左侧的最靠右的颜色和右侧的最靠左的颜色相同的时候要答案减一.然后在树上跳的时候也是注意这个点.

然后因为我很呆,实现在树上跳的时候就用的两个结构体分别存了两侧的数量和边界颜色.

然后我发现到最后一步两个合并的时候我分不出左右就$GG$了,,,$QAQ$

然后我又很作,如果改成直接查询数量和左右节点就简单很多了,,,但我就是不想重构然后就疯狂拍疯狂$WA$疯狂调.

调了一年总算调完了$kk$

其实理顺思路的话还是没那么难的$kk$

$over$,反正就多理下思路注意到底怎么合并就完事$kk$.

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rc register char
#define rb register bool
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt) const int N=1e5+;
int n,m,col[N],ed_cnt,head[N],dfn[N],dfn_cnt,rk[N],top[N],sz[N],sn[N],dep[N],fa[N],qwq;
struct ed{int to,nxt;}edge[N<<];
struct node{int num,l,r,tag;node(ri x=,ri y=,ri z=,ri p=){num=x,l=y,r=z,tag=p;}void print(){printf("(%d,%d,%d)",num,l,r);}}tr[N<<]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il bool rd(){rc ch=gc;while(ch!='C' && ch!='Q')ch=gc;return ch=='C';}
void ad(ri x,ri y){edge[++ed_cnt]=(ed){x,head[y]};head[y]=ed_cnt;}
void dfs(ri x)
{sz[x]=;e(i,x)if(!dep[t(i)]){dep[t(i)]=dep[x]+;dfs(t(i));sz[x]+=sz[t(i)];if(sz[t(i)]>sz[sn[x]])sn[x]=t(i);}}
void dfs2(ri x,ri tp)
{
top[x]=tp;rk[dfn[x]=++dfn_cnt]=x;if(sn[x])dfs2(sn[x],tp),fa[sn[x]]=x;
e(i,x)if(!top[t(i)])dfs2(t(i),t(i)),fa[t(i)]=x;
}
il node merge(node gd,node gs)
{
gd.tag=gs.tag=;if(!gd.num)return gs;if(!gs.num)return gd;
gd.num+=gs.num;if(gd.r==gs.l)--gd.num;gd.r=gs.r;return gd;
}
il void pushdown(ri nw,ri l,ri r)
{
if(!tr[nw].tag)return;
tr[nw<<]=tr[nw<<|]=(node){,tr[nw].tag,tr[nw].tag,tr[nw].tag};tr[nw].tag=;
}
void build(ri nw,ri l,ri r)
{
if(l==r)return void(tr[nw]=(node){,col[rk[l]],col[rk[l]]});
ri mid=(l+r)>>;build(nw<<,l,mid);build(nw<<|,mid+,r);tr[nw]=merge(tr[nw<<],tr[nw<<|]);
}
void modify(ri nw,ri l,ri r,ri to_l,ri to_r,ri dat)
{
if(to_l<=l && r<=to_r){return void(tr[nw]=(node){,dat,dat,dat});}
ri mid=(l+r)>>;pushdown(nw,l,r);
if(to_l<=mid)modify(nw<<,l,mid,to_l,to_r,dat);
if(to_r>mid)modify(nw<<|,mid+,r,to_l,to_r,dat);
tr[nw]=merge(tr[nw<<],tr[nw<<|]);
}
node query(ri nw,ri l,ri r,ri to_l,ri to_r)
{
if(to_l<=l && r<=to_r)return tr[nw];
ri mid=(l+r)>>;node ret;pushdown(nw,l,r);
if(to_l<=mid)ret=merge(ret,query(nw<<,l,mid,to_l,to_r));
if(to_r>mid)ret=merge(ret,query(nw<<|,mid+,r,to_l,to_r));
return ret;
} int main()
{
freopen("2486.in","r",stdin);freopen("2486.out","w",stdout);
n=read();m=read();rp(i,,n)col[i]=read();rp(i,,n-){ri x=read(),y=read();ad(x,y);ad(y,x);}
dep[]=;dfs();dfs2(,);build(,,n);
while(m--)
{
rb op=rd();
if(op)
{
ri x=read(),y=read(),z=read();
while(top[x]!=top[y])
{if(dep[top[x]]<dep[top[y]])swap(x,y);modify(,,n,dfn[top[x]],dfn[x],z);x=fa[top[x]];}
if(dep[x]<dep[y])swap(x,y);modify(,,n,dfn[y],dfn[x],z);continue;
}
ri x=read(),y=read();node asx,asy;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{node tmp=query(,,n,dfn[top[y]],dfn[y]);asy.num+=tmp.num-(tmp.r==asy.r);asy.r=tmp.l;y=fa[top[y]];}
else
{node tmp=query(,,n,dfn[top[x]],dfn[x]);asx.num+=tmp.num-(tmp.r==asx.r);asx.r=tmp.l;x=fa[top[x]];}
}
if(dep[x]<dep[y]){node tmp=query(,,n,dfn[x],dfn[y]);asy.num+=tmp.num-(tmp.r==asy.r);asy.r=tmp.l;}
else{node tmp=query(,,n,dfn[y],dfn[x]);asx.num+=tmp.num-(tmp.r==asx.r);asx.r=tmp.l;}
printf("%d\n",asx.num+asy.num-(asx.r==asy.r)); }
return ;
}

洛谷$P2486\ [SDOI2011]$染色 线段树+树链剖分的更多相关文章

  1. 洛谷P2486 [SDOI2011]染色 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2486 首先这是一道树链剖分+线段树的题. 线段树部分和 codedecision P1112 区间连续段 一模一样,所以我们 ...

  2. 洛谷 P2486 [SDOI2011]染色(树链剖分+线段树)

    题目链接 题解 比较裸的树链剖分 好像树链剖分的题都很裸 线段树中维护一个区间最左和最右的颜色,和答案 合并判断一下中间一段就可以了 比较考验代码能力 Code #include<bits/st ...

  3. 洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)

    [题目链接] [思路]: 涉及到树上区间修改操作,所以使用树链剖分,涉及到区间查询,所以使用线段树. update操作时,就正常操作,难点在于query操作的计数. 因为树链剖分的dfs序只能保证一条 ...

  4. 洛谷 P2486 [SDOI2011]染色 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 PushDown与Update Q AC代码 总结与拓展 题面 题目链接 P2486 ...

  5. 洛谷 P4292 - [WC2010]重建计划(长链剖分+线段树)

    题面传送门 我!竟!然!独!立!A!C!了!这!道!题!incredible! 首先看到这类最大化某个分式的题目,可以套路地想到分数规划,考虑二分答案 \(mid\) 并检验是否存在合法的 \(S\) ...

  6. 洛谷P2486 [SDOI2011]染色

    题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例#1: 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C ...

  7. 线段树&数链剖分

    傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...

  8. P2486 [SDOI2011]染色 区间合并+树链剖分(加深对线段树的理解)

    #include<bits/stdc++.h> using namespace std; ; struct node{ int l,r,cnt,lazy; node(,,,):l(l1), ...

  9. P2486 [SDOI2011]染色 区间合并+树链剖分(加深对线段树的理解)

    #include<bits/stdc++.h> using namespace std; ; struct node{ int l,r,cnt,lazy; node(,,,):l(l1), ...

随机推荐

  1. MySQL常用函数大全讲解

    MySQL数据库中提供了很丰富的函数.MySQL函数包括数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数.加密函数.格式化函数等.通过这些函数,可以简化用户的操作.例如,字符串连接函数 ...

  2. uni-app中使用Echarts绘画图表

    enmnm...一般会使用npm下载echarts这个包,但是不知道是我自己的配置问题还是别的原因,一直出不来图线, 于是,把Hello uni-app模板里的那个组件抱过来,然后,成了! 首先, 1 ...

  3. java的System.currentTimeMillis()如何转换成C#的DateTime.Now.Ticks?

    考虑到我们是东八时区的话,应做如下转换: long milli = System.currentTimeMillis() + 8*3600*1000; long ticks = (milli*1000 ...

  4. fastclick使用与 fastclick ios11.3相关bug原因(ios输入框点击变得不灵敏,ios input失焦后,页面上移,点击不了)

    FastClick 移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击.为了能够立即响应用户的点击事件,就有了FastClick. 安装fastc ...

  5. LuaForWindows_v5.1.4-45和lua-5.1.4.tar.gz

    Lua学习笔记(一) 安装调试环境 Lua学习笔记(一) 安装调试环境     觉得自己是该掌握一门脚本语言的时候了,虽然曾经用过C# 和JavaScript 写过Unity3D的脚本.但是,总觉得那 ...

  6. 用diiv实现多个方块居中嵌套--padding

    文章地址 https://www.cnblogs.com/sandraryan/ 案例:用diiv嵌套多个正方形,配合盒模型相关知识,使每个div在他的父元素上居中.(每个div中心点对齐) 涉及到m ...

  7. 【t093】外星密码

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有了防护伞,并不能完全避免2012的灾难.地球防卫小队决定去求助外星种族的帮助.经过很长时间的努力,小 ...

  8. 【u224】传送机

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 刷完牙洗完脸,黄黄同学就要上课去了.可是黄黄同学每次去上课时总喜欢把校园里面的每条路都走一遍,当然,黄 ...

  9. CF1163F Indecisive Taxi Fee

    NOIP之前留的坑 CF1163F Indecisive Taxi Fee 经典问题:删边最短路 在Ta的博客查看 任意找一条最短路E,给E上的点和边新加入一个1~len的编号 最短路上的边变大麻烦 ...

  10. H3C 示例:根据子网数划分子网