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 ...
随机推荐
- Luogu P1134 阶乘问题 【数学/乱搞】 By cellur925
输入输出格式 输入格式: 仅一行包含一个正整数 NN . 输出格式: 一个整数,表示最右边的非零位的值. 输入输出样例 输入样例#1: 12 输出样例#1: 6 说明 USACO Training S ...
- linux ls touch、umask、 chattr
1.$PATH2.ls -al ~ (~ 显示隐藏的文件) 3$ cd ~ // 回到自己的主文件4.cp /var/log/wtmp . //复制到当前目录,最后的“.”不要忘 ls -l /var ...
- SqlParameter 的使用
SqlParameter[] sqlParams = new SqlParameter[2];sqlParams[0] = new SqlParameter("@RoleId", ...
- [POI2007]办公楼biu
Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决 ...
- _bzoj1016 [JSOI2008]最小生成树计数【生成树】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1016 其实原题不叫这个的,而且原题是有一个背景故事的... 首先,容易得知,一个最小生成树不 ...
- That Nice Euler Circuit UVALive - 3263 || 欧拉公式
欧拉定理: 简单多面体的顶点数V.棱数E及面数F间有关系有著名的欧拉公式:V-E+F=2. 设G为任意的连通的平面图,则v-e+f=2,v是G的顶点数,e是G的边数,f是G的面数.(引) 证明(?) ...
- Oracle11g导出dmp并导入Oracle10g的操作记录
Oracle11g导出dmp并导入Oracle10g的操作记录. 操作环境说明: Oracle11g环境:Windows7,Oracle Database 11g Enterprise Edition ...
- Android Dialogs(2)最好用DialogFragment创建Dialog
Creating a Dialog Fragment You can accomplish a wide variety of dialog designs—including custom layo ...
- h5学习-h5嵌入android中
嵌入Android中的h5界面: 将此页面复制到android项目中的assets目录下边: <!DOCTYPE html> <html lang="en"> ...
- LN : leetcode 413 Arithmetic Slices
lc 413 Arithmetic Slices 413 Arithmetic Slices A sequence of number is called arithmetic if it consi ...