题意

一颗有根树,每个点有黑白两种颜色和阀值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. python数据分析经常使用的库

    这个列表包含数据分析经常使用的Python库,供大家使用.1. 网络通用urllib -网络库(stdlib).requests -网络库.grab – 网络库(基于pycurl).pycurl – ...

  2. Java方法参数:

    一个方法不能修改一个基本数据类型的参数 一个方法可以改变一个对象参数的状态 一个方法不能实现让对象参数引用一个新的对象 案例1: 一个方法不能修改一个基本数据类型的参数 String a = &quo ...

  3. Unable to preventDefault inside passive event listener due to target being treated as passive 怎么办?

    本篇为转载,原文链接:https://blog.csdn.net/lijingshan34/article/details/88350456 翻译一下:chrome 监听touch类事件报错:无法被动 ...

  4. 互联网项目中mysql应该选什么事务隔离级别

    引言 开始我们的内容,相信大家一定遇到过下面的一个面试场景 面试官:“讲讲mysql有几个事务隔离级别?” 你:“读未提交,读已提交,可重复读,串行化四个!默认是可重复读” 面试官:“为什么mysql ...

  5. 有关常用的UI组件

    前段时间想看看大家都用什么UI组件,下面是在网上搜集的,记录在这里方便自己使用和其他小伙伴使用 1:WeUI 小程序–使用教程 https://weui.io/ 官方介绍:WeUI 是一套同微信原生视 ...

  6. 洛谷$P$2286 宠物收养场 $[HNOI2004]$ $splay$

    正解:$splay$ 解题报告: 传送门! $splay$板子,,,? 先考虑这题要实现些什么东西嘛$QwQ$ 其实只要实现一个东西?就查询数列中与给定数字相差最小的数,显然用$splay$查询前驱后 ...

  7. $Noip2016/Luogu2822$ 组合数问题

    $Luogu$ 看这题题解的时候看到一个好可爱的表情(●'◡'●)ノ♥ $Sol$ 首先注意到这题的模数是$k$.然而$k$并不一定是质数,所以不能用$C_n^m=\frac{n!}{m!(n-m)! ...

  8. 前端模块化——彻底搞懂AMD、CMD、ESM和CommonJS

    我们知道,在NodeJS之前,由于没有过于复杂的开发场景,前端是不存在模块化的,后端才有模块化.NodeJS诞生之后,它使用CommonJS的模块化规范.从此,js模块化开始快速发展. 模块化的开发方 ...

  9. 解决mariadb字符级不是utf8问题

    解决方法:在my.cnf配置文件中添加如下几个指令 [client]  default-character-set=utf8 [mysqld] character-set-server=utf8 in ...

  10. html 贪吃蛇代码

    最近在搞自己的网站,维护的时候准备放个贪吃蛇上去,顶一下原有的页面. 这个贪吃蛇有一点毒.原来设定了100级:100级刚开局就挂了.后来改掉了选项菜单,修复了. 还有什么bug,欢迎点击侧边的QQ按钮 ...