noi.ac NOIP2018 全国热身赛 第二场 T3 color

【题解】
我们可以发现每次修改之后叶子结点到根的路径最多分为两段:一段白色或者黑色,上面接另一段灰色的。二分+倍增找到分界点,然后更新答案即可。
check的时候只需要判断当前节点对应的叶子结点的区间是否全部为同一种颜色,用树状数组维护所有叶子节点组成的序列的状态即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#define LL long long
#define rg register
#define N 200010
using namespace std;
int n,m,rt,cnt,ans0,ans1,l[N],r[N],t[N],col[N],dep[N],pos[N],lea[N],p[N][];
vector<int>son[N];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
void dfs(int x){
dep[x]=dep[p[x][]]+;
if(!son[x].size()){
if(col[x]==) ans1++;else ans0++;
pos[x]=l[x]=r[x]=++cnt; lea[cnt]=x; return;
}
int cnt0=,cnt1=;
for(rg int i=;i<(int)son[x].size();i++){
dfs(son[x][i]);
l[x]=min(l[x],l[son[x][i]]); r[x]=max(r[x],r[son[x][i]]);
if(!col[son[x][i]]) cnt0++;
else if(col[son[x][i]]==) cnt1++;
}
if(cnt0==(int)son[x].size()) col[x]=,ans0++;
else if(cnt1==(int)son[x].size()) col[x]=,ans1++;
else col[x]=;
}
inline void add(int x,int y){for(;x<=n;x+=x&-x)t[x]+=y;}
inline int query(int x){int ret=;for(;x;x-=x&-x)ret+=t[x];return ret;}
int main(){
memset(l,0x7f,sizeof(l));
memset(r,,sizeof(r));
n=read(); m=read();
for(rg int i=;i<=n;i++){
son[p[i][]=read()].push_back(i);
if(!p[i][]) rt=i;
}
for(rg int i=;i<=n;i++) col[i]=read();
dfs(rt);
// for(rg int i=1;i<=n;i++) printf("[%d %d]\n",l[i],r[i]);
for(rg int j=;j<;j++)
for(rg int i=;i<=n;i++) p[i][j]=p[p[i][j-]][j-];
for(rg int i=;i<=n;i++) add(i,col[lea[i]]);
// printf("%d %d %d\n",ans1,ans0,n-ans0-ans1);
while(m--){
int x=read(),y=x;
if(col[x]){
for(rg int i=;i>=;i--)if(p[y][i]){
int pa=p[y][i],sum=query(r[pa])-query(l[pa]-);
if(sum==r[pa]-l[pa]+) y=pa;
}
ans1-=dep[x]-dep[y]+;
// printf("y=%d\n",y);
add(pos[x],-); y=x;
for(rg int i=;i>=;i--)if(p[y][i]){
int pa=p[y][i],sum=query(r[pa])-query(l[pa]-);
if(sum==) y=pa;
}
ans0+=dep[x]-dep[y]+;
// printf("y=%d\n",y);
}
else{
for(rg int i=;i>=;i--)if(p[y][i]){
int pa=p[y][i],sum=query(r[pa])-query(l[pa]-);
if(sum==) y=pa;
}
ans0-=dep[x]-dep[y]+;
// printf("y=%d\n",y);
add(pos[x],); y=x;
for(rg int i=;i>=;i--)if(p[y][i]){
int pa=p[y][i],sum=query(r[pa])-query(l[pa]-);
if(sum==r[pa]-l[pa]+) y=pa;
}
ans1+=dep[x]-dep[y]+;
// printf("y=%d\n",y);
}
col[x]^=;
printf("%d %d %d\n",ans1,ans0,n-ans0-ans1);
}
return ;
}
noi.ac NOIP2018 全国热身赛 第二场 T3 color的更多相关文章
- noi.ac NOIP2018 全国热身赛 第二场 T1 ball
[题解] 可以发现每次推的操作就是把序列中每个数变为下一个数,再打一个减一标记:而每次加球的操作就是把球的位置加上标记,再插入到合适的位置. 用set维护即可. #include<cstdio& ...
- NOIP2018 全国热身赛 第二场 (不开放)
NOIP2018 全国热身赛 第二场 (不开放) 题目链接:http://noi.ac/contest/26/problem/60 一道蛮有趣的题目. 然后比赛傻逼了. 即将做出来的时候去做别的题了. ...
- NOI.AC NOIP2018 全国热身赛 第四场
心路历程 预计得分:\(0 + 100 +100\) 实际得分:\(10 + 100 + 0\) 神TM T3模数为啥是\(1e9 + 9\)啊啊啊啊,而且我也确实是眼瞎...真是血的教训啊.. T2 ...
- noi.ac NOIP2018 全国热身赛 第四场 T1 tree
[题解] 考虑从小到大枚举边权,按顺序加边. 当前树被分成了若干个联通块,若各个块内的点只能跟块外的点匹配,那么最终的min g(i,pi)一定大于等于当前枚举的边. 判断各个联通块内的点是否全部能跟 ...
- noi.ac NOIP2018 全国热身赛 第四场 T2 sort
[题解] 跟51nod 1105差不多. 二分答案求出第L个数和第R个数,check的时候再套一个二分或者用two pointers. 最后枚举ai在b里面二分,找到所有范围内的数,排序后输出. 注意 ...
- NOI.AC NOIP模拟赛 第二场 补记
NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...
- NOI.AC: NOIP2018 全国模拟赛习题练习
闲谈: 最后一个星期还是不浪了,做一下模拟赛(还是有点小虚) #30.candy 题目: 有一个人想买糖吃,有两家商店A,B,A商店中第i个糖果的愉悦度为Ai,B商店中第i个糖果的愉悦度为Bi 给出n ...
- NOI.AC NOIP模拟赛 第一场 补记
NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...
- # NOI.AC省选赛 第五场T1 子集,与&最大值
NOI.AC省选赛 第五场T1 A. Mas的童年 题目链接 http://noi.ac/problem/309 思路 0x00 \(n^2\)的暴力挺简单的. ans=max(ans,xor[j-1 ...
随机推荐
- ______________从时间超限到800ms 到200ms——————2098
分拆素数和 Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): Accepted S ...
- python爬虫爬取汽车页面信息,并附带分析(静态爬虫)
环境: windows,python3.4 参考链接: https://blog.csdn.net/weixin_36604953/article/details/78156605 代码:(亲测可以运 ...
- _bzoj2038 [2009国家集训队]小Z的袜子(hose)【莫队】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 裸的莫队,注意要先移动右端点再移动左端点. #include <cstdio&g ...
- AJPFX总结面向对象特征之一的继承知识
继 承(面向对象特征之一) 好处: 1:提高了代码的复用性. 2:让类与类之间产生了关系,提供了另一个特征多态的前提. 父类的由来:其实是由多个类不断向上抽取共性内容而来的. java中对于继承, ...
- AJPFX关于数组获取最值的思路和方法
思路分析:1.定义一个变量(max,初始值一般为数组中的第一个元素值),用来记录最大值.2.遍历数组,获取数组中的每一个元素,然后依次和max进行比较.如果当前遍历到的元素比max大,就把当前元素值给 ...
- Java核心技术梳理-异常处理
一.引言 异常总是不可避免的,就算我们自身的代码足够优秀,但却不能保证用户都按照我们想法进行输入,就算用户按照我们的想法进行输入,我们也不能保证操作系统稳定,另外还有网络环境等,不可控因素太多,异常也 ...
- 工厂方法模式及php实现
工厂方法模式: 工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Facto ...
- LN : leetcode 413 Arithmetic Slices
lc 413 Arithmetic Slices 413 Arithmetic Slices A sequence of number is called arithmetic if it consi ...
- 唤醒键盘时取消对特定类的position:fixed定位
/* 唤起键盘时取消对特定类的position:fixed定位 */ var windheight = $(window).height(); /*未唤起键盘时当前窗口高度*/ $(window).r ...
- schtasks /create 计划任务 中文路径 名字都要加“” 子命令 /tn /tr 前面要空格 否则会出错
echo off echo. 清空连接 net use * /del /y echo. 连接 net use \\192.168.1.2\人力资源部\考勤\考勤数据-小莫提供 "密码&quo ...