树链剖分模板题。线段树维护每个段中的颜色数、左端点颜色、右端点颜色。

pushup: col[rt]=col[rt<<1]+col[rt<<1|1]-(Rcol[rt<<1]==Lcol[rt<<1|1]);

在合并各个链的答案时,要注意若两头颜色相同,ans--。
【教训:树链剖分题在进行建立线段树树时,要注意下面代码中的标注部分。否则会WA】
Code:
 #include<cstdio>
#include<algorithm>
using namespace std;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define maxn 100001
int col[maxn<<],L[maxn<<],R[maxn<<],delta[maxn<<],n,m,Val[maxn],Num[maxn];
int V[maxn<<],First[maxn<<],Next[maxn<<],All_Lcol,All_Rcol,en;
bool vis[maxn];
int top[maxn],son[maxn],tot,dep[maxn],fa[maxn],siz[maxn],Map[maxn];
inline void AddEdge(const int &UU,const int &VV){V[++en]=VV;Next[en]=First[UU];First[UU]=en;}
inline void pushup(const int &rt)
{
L[rt]=L[rt<<];
R[rt]=R[rt<<|];
col[rt]=col[rt<<]+col[rt<<|]-(R[rt<<]==L[rt<<|]);
}
inline void pushdown(const int &rt)
{
if(delta[rt]!=-)
{
L[rt<<]=R[rt<<]=L[rt<<|]=R[rt<<|]=delta[rt];
delta[rt<<]=delta[rt<<|]=delta[rt];
delta[rt]=-;
col[rt<<]=col[rt<<|]=;
}
}
void buildtree(int rt,int l,int r)
{
delta[rt]=-;
if(l==r)
{
col[rt]=;
L[rt]=R[rt]=Val[Map[l]];//l是线段树中的新位置,
//Map[l]表示新位置对应的在树中的编号是谁
return;
}
int m=l+r>>;
buildtree(lson);
buildtree(rson);
pushup(rt);
}
void update(int ql,int qr,int v,int rt,int l,int r)
{
if(ql<=l&&r<=qr)
{
delta[rt]=L[rt]=R[rt]=v;//更新当前结点的标记值
col[rt]=;
return;
}
pushdown(rt);//将该节点的标记下传到孩子们
int m=l+r>>;
if(ql<=m)
update(ql,qr,v,lson);
if(m<qr)
update(ql,qr,v,rson);
pushup(rt);
}
int query(int ql,int qr,int rt,int l,int r)
{
if(ql==l)
All_Lcol=L[rt];
if(r==qr)
All_Rcol=R[rt];
if(ql<=l&&r<=qr)
return col[rt];
pushdown(rt);//将该节点的标记下传到孩子们
int m=l+r>>,res=,now1=-,now2=-;
if(ql<=m)
{
res+=query(ql,qr,lson);
now1=R[rt<<];
}
if(m<qr)
{
res+=query(ql,qr,rson);
now2=L[rt<<|];
}
res-=(now1==now2 && now1!=-);
return res;
}
inline void Update(int u,int v,int val)
{
int f1=top[u],f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(u,v);
swap(f1,f2);
}
update(Num[f1],Num[u],val,,,n);
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])
swap(u,v);
update(Num[v],Num[u],val,,,n);
}
inline int Query(int u,int v)
{
int f1=top[u],f2=top[v],ans=,t1=-,t2=-;
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(u,v);
swap(f1,f2);
swap(t1,t2);
}
ans+=query(Num[f1],Num[u],,,n);
ans-=(t1==All_Rcol);
t1=All_Lcol;
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])
{
swap(u,v);
swap(t1,t2);
}
ans+=query(Num[v],Num[u],,,n);
ans-=((t1==All_Rcol&&t1!=-)+(t2==All_Lcol&&t2!=-));
return ans;
}
void dfs1(int cur,int father,int depth)
{
fa[cur]=father;
dep[cur]=depth;
siz[cur]=;
for(int i=First[cur];i;i=Next[i])
if(!vis[V[i]])
{
vis[V[i]]=true;
dfs1(V[i],cur,depth+);
siz[cur]+=siz[V[i]];
if(siz[V[i]]>siz[son[cur]])
son[cur]=V[i];
vis[V[i]]=false;
}
}
void dfs2(int cur)
{
if(son[cur]&&!vis[son[cur]])
{
vis[son[cur]]=true;
top[son[cur]]=top[cur];
Num[son[cur]]=++tot;
Map[tot]=son[cur];
dfs2(son[cur]);
vis[son[cur]]=false;
}
for(int i=First[cur];i;i=Next[i])
if(son[cur]!=V[i]&&!vis[V[i]])
{
vis[V[i]]=true;
top[V[i]]=V[i];
Num[V[i]]=++tot;
Map[tot]=V[i];
dfs2(V[i]);
vis[V[i]]=false;
}
}
int Res,num;
char C;
char CH[];
inline int getint()
{
Res=;
C='*';
while(C<''||C>'')
C=getchar();
while(C>=''&&C<='')
{
Res=Res*+(C-'');
C=getchar();
}
return Res;
}
inline void putint(int x)
{
num=;
while(x>)
CH[++num]=x%,x/=;
while(num)
putchar(CH[num--]+);
putchar('\n');
}
int main()
{
int x,y,a,b,c;
char op;
n=getint();
m=getint();
for(int i=;i<=n;i++)
Val[i]=getint();
for(int i=;i<n;i++){x=getint();y=getint();AddEdge(x,y);AddEdge(y,x);}
top[]=;
Num[]=++tot;
Map[tot]=;
vis[]=true;
dfs1(,,);
dfs2();
buildtree(,,n);
for(int i=;i<=m;i++)
{
getchar();
op=getchar();
a=getint();
b=getint();
if(op=='C')
{
c=getint();
Update(a,b,c);
}
else
putint(Query(a,b));
}
return ;
}

【树链剖分】bzoj2243 [SDOI2011]染色的更多相关文章

  1. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  2. bzoj-2243 2243: [SDOI2011]染色(树链剖分)

    题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6267  Solved: 2291 Descript ...

  3. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

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

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...

  5. BZOJ2243 SDOI2011 染色 【树链剖分】

    BZOJ2243 SDOI2011 染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色 ...

  6. [BZOJ2243][SDOI2011]染色 解题报告|树链剖分

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...

  7. BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

    题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...

  8. BZOJ2243: [SDOI2011]染色(树链剖分/LCT)

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...

  9. 【BZOJ2243】【SDOI2011】染色(树链剖分,线段树)

    题面 我们也要换个花样,这回提供洛谷的题面 题解 线段树+树链剖分大水题 维护颜色段的方法很简单呀... 维护当前区间内的颜色段个数, 以及当前区间左端和右端的颜色, 合并的时候考虑是否要减一下就行了 ...

随机推荐

  1. bzoj 1004 burnside 引理+DP

    对于burnside引理需要枚举染色,这道题属于burnside的一种简单求解的方法,就是polya,我们可以使每一种置换中的循环节中的元素的颜色都相同,那么这样的话就可以直接DP了,我们可以将m个置 ...

  2. hdu 1233 还是畅通工程 (最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    ...

  3. application.properties 文件的优先级

    bootstrapProperties #来自configServer的值 commandLineArgs #命令行参数 servletConfigInitParams servletContextI ...

  4. LCD实验学习笔记(七):NAND FLASH

    s3c2440 CPU内置NAND FLASH控制器.相关寄存大器起始地址为0x4e000000. 通过设置NFCONF寄存器,设置NAND FLASH 时序. 通过设置NFCONT寄存器,使能NAN ...

  5. LeetCode 20 Generate Parentheses

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...

  6. JS阶段测试

    JS阶段测试 一.选择题 1.表单中的数据要提交到的处理文件由表单的( c )属性指定. A. method     B. name    C. action    D. 以上都不对 2.在CSS样式 ...

  7. 使用GDB命令行调试器调试C/C++程序【转】

    转自:https://linux.cn/article-4302-1.html 编译自:http://xmodulo.com/gdb-command-line-debugger.html作者: Adr ...

  8. 内存分配器memblock【转】

    转自:http://blog.csdn.net/kickxxx/article/details/54710243 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 背景 Data ...

  9. 2017多校第10场 HDU 6172 Array Challenge 猜公式,矩阵幂

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6172 题意:如题. 解法: #include <bits/stdc++.h> using ...

  10. 各种好用的代码生成器(C#)

    各种好用的代码生成器(C#) 1:CodeSmith 一款人气很旺国外的基于模板的dotnet代码生成器 官方网站:http://www.codesmithtools.com 官方论坛:http:// ...