解题: 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\) 个关键点.询问切断一些边,使这些点到根节点不连通, ...
随机推荐
- django-simple_tag、filter
simple_tag与filter的用法 1.支持自定义函数处理方法 2.支持模板调用 创建步骤: a.在app目录下创建templatetags文件夹 b.在templatetags中创建任意名称. ...
- Hyperledger Fabric Ledger——账本总账
Ledger Ledger(账本)即所有的state transitions(状态切换),是有序且不可篡改的.state transitions(状态切换)是由参与方提交的chaincode(智能合约 ...
- nodejs 中jead模板改为ejs
var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set(' ...
- python3去除字符串中括号及括号里面的内容
a = """ <option value="search-alias=arts-crafts-intl-ship">Arts & ...
- Tomcat ngxin 反向代理
tomcat nginx 反向代理 安装nginx yum直接安装 yum install nginx –y 也可以编译安装 这是用编译安装,新手可以用yum安装 配置文件在 /etc/nginx/c ...
- 升级Xcode 10 后报错问题记录([CP] Copy Pods Resources)
1.升级Xcode到Version 10.0 (10A255)后,运行已有项目,报如下错误: error: Multiple commands produce '/Users/galahad/Libr ...
- 20135316王剑桥 linux第四周课实验笔记
第三章 程序的机器级表示 3.1历史观点 Intel处理器的换代:8086——80286——i386——i486——Pentium——PentiumPro——PentiumII——PentiumIII ...
- Task 6.4 冲刺Two之站立会议4
今天对主界面部分的代码进行了完善,因为主界面有对于用户账号的设置.包括头像修改.增删好友.进入聊天界面等功能,包含的内容很多.我主要是负责跟聊天界面的连接以及账号设置的部分:遇到的问题有,因为这部分依 ...
- 增加ubuntu的内存——设置Swap增加内存
1.查看一下当前Swap分区的状态: $cat /proc/meminfo SwapTotal: 0 kB SwapFree: 0 kB 如果上面二项目都为0,说明没有Swap分区:如果不为0,则说明 ...
- DPDK RX / TX Callbacks 源码阅读
这个sample是基于basicfw的.basicfw就是一个网口收到的包立即从另一个网口转发出去,非常简洁明了的程序,可以通过basicfw学习基础的DPDK发包API.RX / TX Callba ...