[Luogu 2486] SDOI2011 染色

<题目链接>


树剖水题,线段树维护。

详细题解不写了。

我只想说我写的线段树又变漂亮了qwq


#include <algorithm>
#include <cstdio>
#include <cstring>
const int MAXN=100010;
int n,m;
class HLD
{
private:
bool vis[MAXN];
int num;
static int rank[MAXN];
static struct Node
{
int v,depth,father,son,top,size,DFN;
}s[MAXN];
class SegmentTree
{
private:
struct Node
{
int v,left,right,lazy,color[2];
Node *c[2];
Node(int l,int r):left(l),right(r),lazy(0)
{
memset(color,0,sizeof color);
c[0]=c[1]=nullptr;
if(l==r)
{
v=1;
color[0]=color[1]=s[rank[l]].v;
return;
}
int mid=l+r>>1;
c[0]=new Node(l,mid);
c[1]=new Node(mid+1,r);
PushUp();
}
~Node(void)
{
if(c[0]!=nullptr)
delete c[0];
if(c[1]!=nullptr)
delete c[1];
}
void Modify(int x)
{
v=1;
lazy=color[0]=color[1]=x;
}
void PushUp(void)
{
v=c[0]->v+c[1]->v;
color[0]=c[0]->color[0];
color[1]=c[1]->color[1];
if(c[0]->color[1]==c[1]->color[0])
--v;
}
void PushDown(void)
{
if(c[0]!=nullptr)
c[0]->Modify(lazy);
if(c[1]!=nullptr)
c[1]->Modify(lazy);
lazy=0;
}
int Color(int x)
{
if(left==right)
return color[0];
if(lazy)
PushDown();
int mid=left+right>>1;
if(x>mid)
return c[1]->Color(x);
else
return c[0]->Color(x);
}
void Change(int l,int r,int v)
{
if(l==left && r==right)
{
Modify(v);
return;
}
if(lazy)
PushDown();
int mid=left+right>>1;
if(r<=mid)
c[0]->Change(l,r,v);
else if(l>mid)
c[1]->Change(l,r,v);
else
{
c[0]->Change(l,mid,v);
c[1]->Change(mid+1,r,v);
}
PushUp();
}
int Query(int l,int r)
{
if(l==left && r==right)
return v;
int mid=left+right>>1;
if(lazy)
PushDown();
if(r<=mid)
return c[0]->Query(l,r);
else if(l>mid)
return c[1]->Query(l,r);
else
{
int ans=c[0]->Query(l,mid)+c[1]->Query(mid+1,r);
if(c[0]->color[1]==c[1]->color[0])
--ans;
return ans;
}
}
}*root;
public:
SegmentTree(int n)
{
root=new Node(1,n);
}
~SegmentTree(void)
{
delete root;
}
int Color(int x)
{
return root->Color(x);
}
void Change(int l,int r,int v)
{
root->Change(l,r,v);
}
int Query(int l,int r)
{
return root->Query(l,r);
}
}*T;
struct Edge
{
int to;
Edge *next;
Edge(int to,Edge* next):to(to),next(next){}
~Edge(void)
{
if(next!=nullptr)
delete next;
}
}*head[MAXN];
void AddEdges(int u,int v)
{
head[u]=new Edge(v,head[u]);
head[v]=new Edge(u,head[v]);
}
void DFS1(int u,int k)
{
s[u].depth=k;
s[u].size=1;
int v;
for(Edge *i=head[u];i!=nullptr;i=i->next)
if(!s[v=i->to].size)
{
DFS1(v,k+1);
s[v].father=u;
s[u].size+=s[v].size;
if(s[v].size>s[s[u].son].size)
s[u].son=v;
}
}
void DFS2(int u,int top)
{
s[u].top=top;
s[u].DFN=++num;
rank[num]=u;
vis[u]=true;
if(s[u].son)
DFS2(s[u].son,top);
int v;
for(Edge *i=head[u];i!=nullptr;i=i->next)
if(!vis[v=i->to])
DFS2(v,v);
}
public:
HLD(int n):num(0)
{
memset(s,0,sizeof s);
std::fill(head+1,head+n+1,nullptr);
for(int i=1;i<=n;++i)
scanf("%d",&s[i].v);
for(int i=1,u,v;i<n;++i)
{
scanf("%d %d",&u,&v);
AddEdges(u,v);
}
DFS1(1,1);
DFS2(1,1);
T=new SegmentTree(n);
}
~HLD(void)
{
for(int i=1;i<=n;++i)
delete head[i];
delete T;
}
void Change(int x,int y)
{
int a,b,v;
scanf("%d",&v);
while((a=s[x].top)^(b=s[y].top))
if(s[a].depth>s[b].depth)
{
T->Change(s[a].DFN,s[x].DFN,v);
x=s[a].father;
}
else
{
T->Change(s[b].DFN,s[y].DFN,v);
y=s[b].father;
}
if(s[x].depth<s[y].depth)
T->Change(s[x].DFN,s[y].DFN,v);
else
T->Change(s[y].DFN,s[x].DFN,v);
}
void Query(int x,int y)
{
int a,b,ans=0;
while((a=s[x].top)^(b=s[y].top))
if(s[a].depth>s[b].depth)
{
ans+=T->Query(s[a].DFN,s[x].DFN);
x=s[a].father;
if(T->Color(s[a].DFN)==T->Color(s[x].DFN))
--ans;
}
else
{
ans+=T->Query(s[b].DFN,s[y].DFN);
y=s[b].father;
if(T->Color(s[b].DFN)==T->Color(s[y].DFN))
--ans;
}
ans+=s[x].depth<s[y].depth ? T->Query(s[x].DFN,s[y].DFN) : T->Query(s[y].DFN,s[x].DFN);
printf("%d\n",ans);
}
}*T;
int HLD::rank[MAXN];
HLD::Node HLD::s[MAXN];
int main(int argc,char** argv)
{
scanf("%d %d",&n,&m);
T=new HLD(n);
char c;
for(int i=1,x,y;i<=m;++i)
{
scanf("\n%c %d %d",&c,&x,&y);
if(c=='C')
T->Change(x,y);
else
T->Query(x,y);
}
delete T;
return 0;
}

谢谢阅读。

[Luogu 2486] SDOI2011 染色的更多相关文章

  1. Luogu P2486 [SDOI2011]染色(树链剖分+线段树合并)

    Luogu P2486 [SDOI2011]染色 题面 题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例: 6 5 2 2 1 2 1 1 1 ...

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

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

  3. luogu P2486 [SDOI2011]染色

    树剖做法: 就是两个dfs+一个线段树 难度的取决基本==线段树的维护难度 所以对有点线段树基础的,树剖也不难做吧 这里操作有二 一:两点间路径染色 线段树的区间赋值操作 二:查询路径段的个数 考虑线 ...

  4. [SDOI2011]染色(树链剖分)

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

  5. BZOJ 2243: [SDOI2011]染色 [树链剖分]

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

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

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

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

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

  8. bzoj2243:[SDOI2011]染色

    链剖就可以了.一开始的想法错了.但也非常接近了.妈呀调的要死...然后把字体再缩小一号查错起来比较容易QAQ. #include<cstdio> #include<cstring&g ...

  9. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

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

随机推荐

  1. 寒假学习计划(C++)

    课程 1,计算机程序设计(C++)-西安交通大学(中国大学mooc)课程链接 2,面向对象程序设计-C++-浙大-翁恺(网易云课堂)课程链接 理由 1西安交大的C++慕课从零基础教起,更注重基础,重点 ...

  2. a5

    今日内容: 今天主要还是素材的查找,图标的制作以及调整. 明日计划: 主要还是完成图标,尽可能的美化 困难: 一个是直男式的审美吧,另一个是PS的技术还不够深

  3. HDU 5183 Negative and Positive (NP) 前缀和+哈希

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5183 bc(中文):http://bestcoder.hdu.edu.cn/contests ...

  4. C++中使用内存映射文件处理大文件

    引言 文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile().WriteFile().ReadFile() ...

  5. Java多线程编程(学习笔记)

    一.说明 周末抽空重新学习了下多线程,为了方便以后查阅,写下学习笔记. 有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候需要利用多线程编程. 通过 ...

  6. Spring mvc 数据验证框架注解

    @AssertFalse 被注解的元素必须为false@AssertTrue 被注解的元素必须为false@DecimalMax(value) 被注解的元素必须为一个数字,其值必须小于等于指定的最小值 ...

  7. postman优缺点

    postman优缺点分析 优点:门槛低,上手快 优点: 脚本语言是js 优点:自带各种代码模块 优点:跨平台 优点: 免费版就已经非常强大了,支持http,https协议 优点:有命令行版本,newm ...

  8. jQuery表单验证组件BootstrapValidator

    github:https://github.com/nghuuphuoc/bootstrapvalidator 参考博客:JS组件系列——Form表单验证神器: BootstrapValidator ...

  9. 第147天:web前端开发中的各种居中总结

    一.水平居中 方法① :行内元素 (父元素)text-align,(子元素)inline-block .parent{text-align: center;} .child{display: inli ...

  10. dom变成jquery对象 先获取dom对象 然后通过$()转换成jquery对象

    dom变成jquery对象   先获取dom对象 然后通过$()转换成jquery对象