[集训]Evocation
题意
一颗有根树,每个点有黑白两种颜色和阀值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的更多相关文章
- QDEZ集训笔记【更新中】
这是一个绝妙的比喻,如果青岛二中的台阶上每级站一只平度一中的猫,差不多站满了吧 自己的理解 [2016-12-31] [主席树] http://www.cnblogs.com/candy99/p/61 ...
- 2015UESTC 暑假集训总结
day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...
- JS省队集训记
不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...
- 2013ACM暑假集训总结-致将走上大三征途的我
回想起这个暑假,从开始与雄鹰一起的纠结要不要进集训队,与吉吉博博组队参加地大邀请赛,害怕进不了集训队.当时激励我月份开始接触的,记得当时在弄运动会来着,然后就问了雄鹰一些输入输出的东西,怀着满心的期待 ...
- 至芯FPGA培训中心-1天FPGA设计集训(赠送FPGA开发板)
至芯FPGA培训中心-1天FPGA设计集训(赠送开发板) 开课时间2014年5月3日 课程介绍 FPGA设计初级培训班是针对于FPGA设计技术初学者的课程.课程不仅是对FPGA结构资源和设计流程的描述 ...
- 2014年CCNU-ACM暑期集训总结
2014年CCNU-ACM暑期集训总结 那个本期待已久的暑期集训居然就这种.溜走了.让自己有点措手不及.很多其它的是对自己的疑问.自己是否能在ACM这个领域有所成就.带着这个疑问,先对这个暑假做个总结 ...
- [补档] 大假期集训Part.1
新博客搭起来先补一发档... 那就从大假期集训第一部分说起好了QwQ 自己还是太菜掉回了2016级水平 day1: day1的时候来得有点晚(毕竟准高一)然后进机房发现早就开考了还没有给我题面于是搞了 ...
- [补档]暑假集训D6总结
考试 不是爆零,胜似爆零= = 三道题,就拿了20分,根本没法玩好吧= = 本来以为打了道正解,打了道暴力,加上个特判分,应该不会死的太惨,然而--为啥我只有特判分啊- - 真的是惨. 讲完题觉得题是 ...
- [补档]暑假集训D5总结
%dalao 今天又有dalao来讲课,讲的是网络流 网络流--从入门到放弃:7-29dalao讲课笔记--https://hzoi-mafia.github.io/2017/07/29/27/ ...
随机推荐
- Tomcat 类加载器打破双亲委派模型
我们分为4个部分来探讨: 1. 什么是类加载机制? 2. 什么是双亲委任模型? 3. 如何破坏双亲委任模型? 4. Tomcat 的类加载器是怎么设计的? 我想,在研究tomcat 类加载之前,我们复 ...
- 阿里云“网红"运维工程师白金:做一个平凡的圆梦人
他是阿里云的一位 P8 运维专家,却很有野心得给自己取花名“辟拾(P10)”:他没有华丽的履历,仅凭着 26 年的热爱与坚持,一步一个脚印踏出了属于自己的技术逆袭之路:他爱好清奇,练就了能在 20 秒 ...
- Jenkins安装部署与使用
一.Jenkins平台安装部署 Jenkins官网免费获取Jenkins软件,官网地址为:http://mirrors.jenkins-ci.org/下载稳定的Jenkins版本.由于Jenkins是 ...
- Cmder安装与使用
越来越多人使用Cmder代替Windows的cmd(毕竟其界面太Lower了),但是每次用Cmder都要回到安装目录查找之后才能使用,真的很麻烦,有木有可以像Git一样右键就是可以用的方法呢?答案当然 ...
- Spring JDBC操作数据库示例
1.所需jar包 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncodi ...
- python接口自动化测试-unittest-生成测试报告
用例的管理问题解决了后,接下来要考虑的就是报告我问题了,这里生成测试报告主要用到 HTMLTestRunner.py 这个模块,下面简单介绍一下如何使用: 一.下载HTMLTestRunner下载: ...
- java 实现敏感词(sensitive word)工具详解使用说明
sensitive-word 平时工作中,只要涉及到用户可以自由发言(博客.文档.论坛),就要考虑内容的敏感性处理. sensitive-word 基于 DFA 算法实现的高性能敏感词工具.工具使用 ...
- java中高级并发SPI机制
Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制. 适用于:调用者根据实际使用需要,启用.扩展.或者替换框架的实现策略. 要使用Java SPI,需要遵循如下约定 ...
- 低副瓣阵列天线综合2 matlab HFSS
接着继续研究阵列天线设计,得到了电流幅度分布或功率分布之后,就可以进行阵列设计或馈电网络设计了,之前利用HFSS仿真过单列的串馈天线,后面会继续复习熟悉一下,本次我找了一篇硕士论文利用威尔金森功分器来 ...
- 流程控制-物流费用计算(嵌套if)
题目描述 快递公司规定,如果物品体积超过2.5立方米,不允许快递.如果重量超过40kg,不允许快递.快递收费价格为: 小于等于1kg,一口价10块钱: 大于1kg,小于等于5kg,10块钱的基础上,每 ...