解题: SDOI 2011 染色
强行把序列问题通过树剖套在树上。。。算了算是回顾了一下树剖的思想=。=
每次树上跳的时候注意跳的同时维护当前拼出来的左右两条链的靠上的端点,然后拼起来的时候讨论一下拼接点,最后一下左右两边的端点都要考虑
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
struct a
{
int cnt;
int lc,rc;
};
int num[N],nmb[N],val[*N],lcol[*N],rcol[*N],laz[*N];
int siz[N],dep[N],anc[N],imp[N],top[N],dfn[N];
int p[N],noww[*N],goal[*N];
int n,m,t1,t2,t3,cnt,tot;
char rd[];
void link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
}
void DFS(int nde,int fth,int dth)
{
int tmp=;
siz[nde]=,anc[nde]=fth,dep[nde]=dth;
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
DFS(goal[i],nde,dth+);
siz[nde]+=siz[goal[i]];
if(siz[goal[i]]>tmp)
tmp=siz[goal[i]],imp[nde]=goal[i];
}
}
void MARK(int nde,int tpp)
{
dfn[nde]=++tot,nmb[tot]=num[nde],top[nde]=tpp;
if(imp[nde])
{
MARK(imp[nde],tpp);
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=anc[nde]&&goal[i]!=imp[nde])
MARK(goal[i],goal[i]);
}
}
void pushup(int nde)
{
int ls=*nde,rs=*nde+;
lcol[nde]=lcol[ls],rcol[nde]=rcol[rs];
val[nde]=val[ls]+val[rs]-(rcol[ls]==lcol[rs]);
}
void create(int nde,int l,int r)
{
if(l==r)
val[nde]=,lcol[nde]=rcol[nde]=nmb[l];
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+;
create(ls,l,mid),create(rs,mid+,r);
pushup(nde);
}
}
void release(int nde,int l,int r)
{
if(laz[nde])
{
int ls=*nde,rs=*nde+;
laz[ls]=lcol[ls]=rcol[ls]=laz[nde];
laz[rs]=lcol[rs]=rcol[rs]=laz[nde];
val[ls]=val[rs]=; laz[nde]=;
}
}
void change(int nde,int l,int r,int nl,int nr,int task)
{
if(l>nr||r<nl)
return ;
else if(l>=nl&&r<=nr)
val[nde]=,lcol[nde]=rcol[nde]=laz[nde]=task;
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+; release(nde,l,r);
change(ls,l,mid,nl,nr,task),change(rs,mid+,r,nl,nr,task);
pushup(nde);
}
}
a query(int nde,int l,int r,int nl,int nr)
{
if(l>=nl&&r<=nr)
return (a){val[nde],lcol[nde],rcol[nde]};
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+; release(nde,l,r);
if(nr<=mid) return query(ls,l,mid,nl,nr);
if(nl>mid) return query(rs,mid+,r,nl,nr);
a r1=query(ls,l,mid,nl,nr),r2=query(rs,mid+,r,nl,nr),ret;
ret.lc=r1.lc,ret.rc=r2.rc,ret.cnt=r1.cnt+r2.cnt-(r1.rc==r2.lc);
return ret;
}
}
void path_change(int x,int y,int v)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
change(,,n,dfn[top[x]],dfn[x],v); x=anc[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
change(,,n,dfn[x],dfn[y],v); return ;
}
int path_query(int x,int y)
{
int rt=,ll=-,rr=-;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y),swap(ll,rr);
a ret=query(,,n,dfn[top[x]],dfn[x]); x=anc[top[x]];
rt+=ret.cnt-(ll==ret.rc); ll=ret.lc;
}
if(dep[x]>dep[y]) swap(x,y),swap(ll,rr);
a ret=query(,,n,dfn[x],dfn[y]); rt+=ret.cnt-(ll==ret.lc)-(rr==ret.rc);
return rt;
}
int main ()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&num[i]);
for(int i=;i<n;i++)
scanf("%d%d",&t1,&t2),link(t1,t2),link(t2,t1);
DFS(,,); MARK(,); create(,,n);
while(m--)
{
scanf("%s",rd);
if(rd[]=='C')
scanf("%d%d%d",&t1,&t2,&t3),path_change(t1,t2,t3);
else
scanf("%d%d",&t1,&t2),printf("%d\n",path_query(t1,t2));
}
return ;
}
解题: SDOI 2011 染色的更多相关文章
- [BZOJ 2243] [SDOI 2011] 染色 【树链剖分】
题目链接:BZOJ - 2243 题目分析 树链剖分...写了200+行...Debug了整整一天+... 静态读代码读了 5 遍 ,没发现错误,自己做小数据也过了. 提交之后全 WA . ————— ...
- BZOJ 2243 SDOI 2011染色
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 算法讨论: 树链剖分把树放到线段树上.然后线段树的每个节点要维护的东西有左端点的颜色 ...
- [SDOI 2011]染色
Description 题库链接 给定一棵有 \(n\) 个节点的无根树和 \(m\) 个操作,操作有 \(2\) 类: 将节点 \(a\) 到节点 \(b\) 路径上所有点都染成颜色 \(c\) : ...
- 解题:SDOI 2011 消耗战
题面 本身求答案是简单的树上DP,只需要求出根到每个点路径上的最小值,然后考虑割连父亲的边还是割所有儿子即可,但是每次都这样做一次显然不能通过,考虑优化 用虚树来优化:虚树是针对树上一些点建出来的一棵 ...
- 【SDOI 2011】染色
[题目链接] 点击打开链接 [算法] 树链剖分 [代码] 本题,笔者求最近公共祖先并没有用树链剖分“往上跳”的方式,而是用倍增法.笔者认为这样比较好写,代码可读性 比较高 此外,笔者的线段树并没有用懒 ...
- 【codevs 1565】【SDOI 2011】计算器 快速幂+拓展欧几里得+BSGS算法
BSGS算法是meet in the middle思想的一种应用,参考Yveh的博客我学会了BSGS的模版和hash表模板,,, 现在才会hash是不是太弱了,,, #include<cmath ...
- [bzoj2286][Sdoi 2011]消耗战
[bzoj2286]消耗战 标签: 虚树 DP 题目链接 题解 很容易找出\(O(mn)\)的做法. 只需要每次都dp一遍. 但是m和n是同阶的,所以这样肯定会T的. 注意到dp的时候有很多节点是不需 ...
- [SDOI 2011]黑白棋
Description 题库链接 给出一个 \(1\times n\) 的棋盘,棋盘上有 \(k\) 个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 \( ...
- [SDOI 2011]消耗战
Description 题库链接 给你一棵 \(n\) 个节点根节点为 \(1\) 的有根树,有边权. \(m\) 次询问,每次给出 \(k_i\) 个关键点.询问切断一些边,使这些点到根节点不连通, ...
随机推荐
- python FTP服务器实现(Python3)
创建一个ftp.py文件(Linux环境),插入以下代码: from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handl ...
- Scrum Meeting 11.07
成员 今日任务 明日计划 用时 徐越 赵庶宏 薄霖 卞忠昊 JOSN数据解析 WebView和JavaScript交互基础 3h 武鑫 设计界面:独立完成一些简 ...
- 小组冲刺第十一天站立会议(发布Alpha版+网站链接)
注: “助成”招聘网站链接:http://58.87.74.131:8080/zhucheng 欢迎大家进行评测. 一.任务看板: 二.燃尽图: 三.团队成员合照: 四.任务总结: 今天我们发布网站B ...
- Python学习二
list [ ] Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素 classmates = ['Michael', 'Bob', 'Tracy ...
- [usaco]2013-jan Liars and Truth Tellers 真假奶牛
Description 约翰有N头奶牛,有一部分奶牛是真话奶牛,它们只说真话,而剩下的是假话奶牛,只说假话.有一天,约翰从奶牛的闲谈中陆续得到了M句话,第i句话出自第Xi头奶牛,它会告诉约翰第Yi头是 ...
- 重学 以太网的mac协议的CSMA/CD
之前上课一直模糊的CSMA/CD进行系统性整理. CSMA/CD (Carrier Sense Multiple Acess/Collision Detect)应用在OSI的 数据链路层 在以太网中, ...
- BeanUtil工具类的使用
BeanUtils的使用 1.commons-beanutils的介绍 commons-beanutils是Apache组织下的一个基础的开源库,它提供了对Java反射和内省的API的包装,依赖内省, ...
- JTS
在这个系列的 第 1 部分,我们讨论了事务并研究了它们的基本属性 ― 原子性(atomicity).一致性(consistency).孤立性(isolation)和持久性(durability).事务 ...
- 消息队列第一篇:MessageQueue介绍
消息队列有哪些好处或功能: 1.消息可以在断开连接的环境下发送.不需要同时运行正在发送和正在接收的应用程序. 2.使用快捷模式,消息可以非常快地发送.在快捷模式下,消息存储在内存中. 3.对于可恢复的 ...
- 区别mouseover与mouseenter?
区别mouseover与mouseenter? * mouseover: 在移入子元素时也会触发, 对应mouseout,进入子元素的时候,父元素显示离开状态 * mouseenter: 只在移入当前 ...