题意

一颗有根树,每个点有黑白两种颜色和阀值ai,若它的子树中(不包括自己)的黑色数量大于ai,则产生一点贡献。每次将一个点的颜色取反,求每次修改后的贡献。n,q<=1E5。


思考

树剖后直接分块就行了。复杂度约为O((n+q)sqrt(nlogn)),但似乎更小?


代码

 #pragma GCC optimize 2
#include<bits/stdc++.h>
using namespace std;
const int maxn=1E5+;
///////////////////////////////////////////////////////////////////////////////
int wait[maxn],wait_R[maxn],wait_C[maxn],wait_W[maxn];
template<class T>inline void copy(T*A,T*B,int l,int r)
{
for(int i=l;i<=r;++i)
A[i-l+]=B[i];
}
struct block
{
int n,pos,layer,now;
bool created;
int*f,*c;
block()
{
created=now=;
}
void init(int x,int where,int*A)
{
if(created)
delete f,delete c;
created=;
for(int i=;i<=x;++i)
wait_R[i]=A[i],wait_C[i]=;
sort(wait_R+,wait_R+x+);
int size=;
for(int i=;i<=x;++i)
{
if(wait_R[i]!=wait_R[i-]||i==)
wait_W[++size]=wait_R[i];
++wait_C[size];
}
n=size;
f=new int[n+];
c=new int[n+];
now=c[]=f[]=c[n+]=f[n+]=;
layer=where;
pos=;
for(int i=;i<=n;++i)
f[i]=wait_W[i],c[i]=wait_C[i];
while(f[pos]<layer)
now+=c[pos],++pos;
}
inline int get()
{
return now;
}
inline void add()
{
if(layer+==f[pos]+)
now+=c[pos],++pos;
++layer;
}
inline void remove()
{
if(pos&&layer-==f[pos-])
now-=c[pos-],--pos;
--layer;
}
};
struct sequence
{
int*a,*tag,*bel,*tail;
block*B;
int n,sqr,tot;
void init(int x,int*A)
{
n=x;
sqr=sqrt(n+0.5);
a=new int[n+];
bel=new int[n+];
tag=new int[sqr+];
tail=new int[sqr+];
for(int i=;i<=sqr+;++i)
tail[i]=tag[i]=;
a[]=;
for(int i=;i<=n;++i)
a[i]=A[i];
int L=,R=sqr;
B=new block[sqr+];
tot=;
while(L<=n)
{
int len=min(n,R)-L+;
copy(wait,a,L,min(n,R));
B[++tot].init(len,,wait);
for(int i=L;i<=R;++i)
bel[i]=tot;
tail[tot]=min(n,R);
L+=sqr,R+=sqr;
}
}
inline int get()
{
int sum=;
for(int i=;i<=tot;++i)
sum+=B[i].now;
return sum;
}
inline void add(int x)
{
int i=;
for(i=;bel[i]!=bel[x];i+=sqr)
B[bel[i]].add();
int L=i,R=tail[bel[x]];
int len=R-L+;
for(int i=L;i<=R;++i)
wait[i-L+]=a[i]-B[bel[x]].layer;
for(int i=L;i<=x;++i)
--wait[i-L+];
for(int i=L;i<=R;++i)
a[i]=wait[i-L+];
B[bel[x]].init(len,,wait);
}
inline void remove(int x)
{
int i=;
for(i=;bel[i]!=bel[x];i+=sqr)
B[bel[i]].remove();
int L=i,R=tail[bel[x]];
int len=R-L+;
for(int i=L;i<=R;++i)
wait[i-L+]=a[i]-B[bel[x]].layer;
for(int i=L;i<=x;++i)
++wait[i-L+];
for(int i=L;i<=R;++i)
a[i]=wait[i-L+];
B[bel[x]].init(len,,wait);
}
inline void addDot(int x,int y)
{
int i=;
while(bel[i]!=bel[x])
i+=sqr;
int L=i,R=tail[bel[x]];
int len=R-L+;
for(int i=L;i<=R;++i)
wait[i-L+]=a[i]-B[bel[x]].layer;
wait[x-L+]+=y;
for(int i=L;i<=R;++i)
a[i]=wait[i-L+];
B[bel[x]].init(len,,wait);
}
}S[maxn];
///////////////////////////////////////////////////////////////////////////////
int n,q,a[maxn];
int size,head[maxn*];
int sum[maxn],fa[maxn],son[maxn],top[maxn],where[maxn],dfn[maxn],low[maxn],ti;
int tot,ans;
bool c[maxn];
struct edge
{
int to,next;
}E[maxn*];
void dfs1(int u,int F)
{
fa[u]=F,sum[u]=;
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(v==F)
continue;
dfs1(v,u);
sum[u]+=sum[v];
if(sum[son[u]]<sum[v])
son[u]=v;
}
}
void dfs2(int u,int F)
{
low[u]=dfn[u]=++ti;
if(son[F]==u)
top[u]=top[F];
else
top[u]=u;
if(son[u])
{
dfs2(son[u],u);
low[u]=low[son[u]];
}
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(v==F||v==son[u])
continue;
dfs2(v,u);
low[u]=low[v];
}
}
void get(int u)
{
wait[where[u]=++tot]=a[u];
if(son[u])
get(son[u]);
}
void add(int u,int v)
{
E[++size].to=v;
E[size].next=head[u];
head[u]=size;
}
void addChain(int x)
{
while(x)
{
S[top[x]].add(where[x]);
x=fa[top[x]];
}
}
void removeChain(int x)
{
while(x)
{
S[top[x]].remove(where[x]);
x=fa[top[x]];
}
}
int askChain(int x)
{
int sum=;
while(x)
{
sum+=S[top[x]].get();
x=fa[top[x]];
}
return sum;
}
///////////////////////////////////////////////////////////////////////////////
int main()
{
ios::sync_with_stdio(false);
int num;
cin>>num;
cin>>n>>q;
for(int i=;i<=n;++i)
{
int x;
cin>>x;
add(x,i);
add(i,x);
}
for(int i=;i<=n;++i)
cin>>a[i];
dfs1(,);
dfs2(,);
fa[]=;
for(int u=;u<=n;++u)
if(top[u]==u)
{
tot=;
get(u);
S[u].init(tot,wait);
}
while(q--)
{
int x;
cin>>x;
if(c[x])
{
int last=askChain(x);
removeChain(fa[x]);
S[top[x]].addDot(where[x],-);
int now=askChain(x);
ans+=now-last;
}
else
{
int last=askChain(x);
addChain(fa[x]);
S[top[x]].addDot(where[x],);
int now=askChain(x);
ans+=now-last;
}
c[x]^=;
cout<<ans<<" ";
}
return ;
}

[集训]Evocation的更多相关文章

  1. QDEZ集训笔记【更新中】

    这是一个绝妙的比喻,如果青岛二中的台阶上每级站一只平度一中的猫,差不多站满了吧 自己的理解 [2016-12-31] [主席树] http://www.cnblogs.com/candy99/p/61 ...

  2. 2015UESTC 暑假集训总结

    day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...

  3. JS省队集训记

    不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...

  4. 2013ACM暑假集训总结-致将走上大三征途的我

    回想起这个暑假,从开始与雄鹰一起的纠结要不要进集训队,与吉吉博博组队参加地大邀请赛,害怕进不了集训队.当时激励我月份开始接触的,记得当时在弄运动会来着,然后就问了雄鹰一些输入输出的东西,怀着满心的期待 ...

  5. 至芯FPGA培训中心-1天FPGA设计集训(赠送FPGA开发板)

    至芯FPGA培训中心-1天FPGA设计集训(赠送开发板) 开课时间2014年5月3日 课程介绍 FPGA设计初级培训班是针对于FPGA设计技术初学者的课程.课程不仅是对FPGA结构资源和设计流程的描述 ...

  6. 2014年CCNU-ACM暑期集训总结

    2014年CCNU-ACM暑期集训总结 那个本期待已久的暑期集训居然就这种.溜走了.让自己有点措手不及.很多其它的是对自己的疑问.自己是否能在ACM这个领域有所成就.带着这个疑问,先对这个暑假做个总结 ...

  7. [补档] 大假期集训Part.1

    新博客搭起来先补一发档... 那就从大假期集训第一部分说起好了QwQ 自己还是太菜掉回了2016级水平 day1: day1的时候来得有点晚(毕竟准高一)然后进机房发现早就开考了还没有给我题面于是搞了 ...

  8. [补档]暑假集训D6总结

    考试 不是爆零,胜似爆零= = 三道题,就拿了20分,根本没法玩好吧= = 本来以为打了道正解,打了道暴力,加上个特判分,应该不会死的太惨,然而--为啥我只有特判分啊- - 真的是惨. 讲完题觉得题是 ...

  9. [补档]暑假集训D5总结

    %dalao 今天又有dalao来讲课,讲的是网络流 网络流--从入门到放弃:7-29dalao讲课笔记--https://hzoi-mafia.github.io/2017/07/29/27/   ...

随机推荐

  1. spring boot 多数据源加载原理

    git代码:https://gitee.com/wwj912790488/multiple-data-sources DynamicDataSourceAspect切面 必须定义@Order(-10) ...

  2. linux c函数参考手册

    一.字符测试 isalnum(测试字符是否为英文字母或数字) isalpha(测试字符是否为英文字母) isascii(测试字符是否为ascii码字符) isblank(测试字符是否为空格字符) is ...

  3. Percona-XtraDB-Cluster 5.7版本(PXC)集群部署

    PXC(Percona-XtraDB-Cluster)5.7版本集群部署 Centos 7.3系统部署Mysql 集群 PXC三个节点分别执行和安装(1)配置hosts cat /etc/hosts1 ...

  4. 0013 CSS复合选择器:后代、子代、交集、并集、超链接伪类

    重点: 复合选择器 后代选择器 并集选择器 标签显示模式 CSS背景 背景位置 CSS三大特性 优先级 1. CSS复合选择器 目标 理解 理解css复合选择器分别的应用场景 应用 使用后代选择器给元 ...

  5. Git安装--Windows

    Git安装配置 在使用Git前我们需要先安装 Git.Git 目前支持 Linux/Unix.Solaris.Mac和 Windows 平台上运行. Git 各平台安装包下载地址为:http://gi ...

  6. 【题解】CF741D(DSU on TREE)

    [题解]CF741D(DSU on TREE) 写一写这道题来学习学习模板 用二进制来转换一下条件,现在就是要求一下\(lowbit(x)=x\)的那些路径了. DSU on TREE 是这样一种算法 ...

  7. DRF 08

    目录 三大认证 流程 认证组件 权限组件 频率组件 自定义token的签发 三大认证 流程 由于DRF中, 所有的视图类都要直接和间接继承APIView类, 也只有APIView类中才有dispatc ...

  8. 14.python案例:爬取电影天堂中所有电视剧信息

    1.python案例:爬取电影天堂中所有电视剧信息 #!/usr/bin/env python3 # -*- coding: UTF-8 -*- '''======================== ...

  9. 【转】[ppurl]从”皮皮书屋”下载电子书的姿势

    转:http://blog.csdn.net/hcbbt/article/details/42072545 写在前面的扯皮 为什么标题的”皮皮书屋”加上了引号,因为皮皮书屋(http://www.pp ...

  10. EFCore Database-first深入研究

    EFCore Database-first深入研究 使用Scaffold-DbContext从数据库生成实体 说明文档: 关于 Scaffold-DbContext 微软有官方说明文档 https:/ ...