[Luogu 2486] SDOI2011 染色
[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 染色的更多相关文章
- Luogu P2486 [SDOI2011]染色(树链剖分+线段树合并)
Luogu P2486 [SDOI2011]染色 题面 题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例: 6 5 2 2 1 2 1 1 1 ...
- BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...
- luogu P2486 [SDOI2011]染色
树剖做法: 就是两个dfs+一个线段树 难度的取决基本==线段树的维护难度 所以对有点线段树基础的,树剖也不难做吧 这里操作有二 一:两点间路径染色 线段树的区间赋值操作 二:查询路径段的个数 考虑线 ...
- [SDOI2011]染色(树链剖分)
[SDOI2011]染色(luogu) Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段 ...
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[Submit][Status ...
- bzoj-2243 2243: [SDOI2011]染色(树链剖分)
题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6267 Solved: 2291 Descript ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- bzoj2243:[SDOI2011]染色
链剖就可以了.一开始的想法错了.但也非常接近了.妈呀调的要死...然后把字体再缩小一号查错起来比较容易QAQ. #include<cstdio> #include<cstring&g ...
- bzoj 2243 [SDOI2011]染色(树链剖分,线段树)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4637 Solved: 1726[Submit][Status ...
随机推荐
- StringBuilder、StringBuffer和String三者的联系和区别
String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a ...
- 【beta】nice!-------约吧NABCD
小组名称:nice! 组长:李权 成员:于淼 刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 约吧APP下载地址: 百度云:链接:http://pan.baidu.com/s/1jHNBR3g ...
- C++变量内存分配及类型修饰符
前言 了解C++程序内存分配,有助于深刻理解变量的初始化值以及其生存周期.另外,变量类型修饰符也会影响到变量的初始化值及其生存周期.掌握了不同类型变量的初始化值及其生存周期,能够让我们设计程序时定义变 ...
- 在64位系统上部署BDE的要点
首先,据我所知,Borland/CodeGear没有发布过支持64bit windows的BDE安装包,如果你在网上看到了相关的BDE安装包,很有可能是使用者自己重新打包发布的. 无论是在32bit ...
- 某客的《微信小程序》从基础到实战视频教程
第 1 部分 微信小程序从基础到实战课程概要 第 1 节 微信小程序从基础到实战课程概要 1.1微信小程序从基础到实战课程概要 第 2 部分 初识微信小程序 第 1 节 微信小程序简 ...
- postman 上一个接口返回值传给下一个接口
问题:如何将A请求responseBody中的token传入B请求中的request中 把A请求中的token设置为环境变量,如下: tests["Status code is 200&qu ...
- 【刷题】HDU 6184 Counting Stars
Problem Description Little A is an astronomy lover, and he has found that the sky was so beautiful! ...
- C++操作Windows WIFI
原文链接地址:https://blog.csdn.net/just_do_1122/article/details/78031024 实现功能 无线网卡列表 无线热点扫面 无线 ...
- 康托展开&康托逆展开 的写法
康托展开 康托展开解决的是当前序列在全排序的名次的问题. 例如有五个数字组成的数列:1,2,3,4,5 那么1,2,3,4,5就是全排列的第0个[注意从0开始计数] 1,2,3,5,4就是第1个 1, ...
- 洛谷 P1715 [USACO16DEC]Lots of Triangles好多三角形 解题报告
P1715 [USACO16DEC]Lots of Triangles好多三角形 题目描述 农民约翰希望通过卖出他拥有的一部分土地来增加收入.他在这片土地上种了\(N\)棵树(\(3\le N\le ...