当前位置:网站首页>2022杭电多校第二场 A.Static Query on Tree(树剖)
2022杭电多校第二场 A.Static Query on Tree(树剖)
2022-07-26 04:28:00 【thusloop】
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
//#define int long long
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define yes cout<<"Yes\n"
#define no cout<<"No\n"
#define yesno if(fg)yes;else no;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=8e18;
const int maxn=2e5+100;
vector<int>g[maxn];
int a[maxn],b[maxn],c[maxn],son[maxn],siz[maxn],fa[maxn];
int dep[maxn],top[maxn],dfn[maxn],rk[maxn],clk,out[maxn];
template <typename T> inline void read(T& x)
{
x=0;
T f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=x*f;
return;
}
template <typename T,typename ...Arg>void read(T& x,Arg& ...arg)
{
read(x);
read(arg...);
}
template <typename T>inline void write(T x)
{
if(x<0)putchar('-'),x=-x;
if(x<10)putchar(x+'0');
else write(x/10),putchar(x%10+'0');
}
template <typename T,typename ...Arg>void write(T& x,Arg& ...arg)
{
write(x);
putchar(' ');
write(arg...);
}
struct node
{
int l,r;
int sum;
int s[8];
int lazy;
int lazy2;//清空标志
} t[maxn*4];
void dfs(int x,int f)
{
fa[x]=f;
dep[x]=dep[f]+1;
siz[x]=1;
son[x]=-1;
for(auto it:g[x])
{
if(it==f)continue;
dfs(it,x);
siz[x]+=siz[it];
if(son[x]==-1||siz[it]>siz[son[x]])son[x]=it;
}
}
void dfs2(int x,int t)
{
top[x]=t;
dfn[x]=++clk;
rk[clk]=x;
if(son[x]==-1)
{
out[x]=clk;
return ;
}
dfs2(son[x],t);
for(auto it:g[x])
{
if(it==fa[x])continue;
if(it==son[x])continue;
dfs2(it,it);
}
out[x]=clk;
}
void push_down(int k)
{
if(t[k].l==t[k].r)
{
t[k].lazy=0;
t[k].lazy2=0;
return ;
}
if(t[k].lazy2)//清空
{
t[k<<1].lazy2=t[k<<1|1].lazy2=1;
t[k<<1].lazy=t[k<<1|1].lazy=0;//note
for(int i=0; i<=7; i++)
{
t[k<<1].s[i]=t[k<<1|1].s[i]=0;
}
t[k<<1].s[0]=t[k<<1].r-t[k<<1].l+1;
t[k<<1|1].s[0]=t[k<<1|1].r-t[k<<1|1].l+1;
t[k].lazy2=0;
}
if(t[k].lazy>0)
{
for(int i=7; i>=0; i--)
{
if((i|t[k].lazy)==i)continue;
t[k<<1].s[i|t[k].lazy]+=t[k<<1].s[i];
t[k<<1].s[i]=0;
t[k<<1|1].s[i|t[k].lazy]+=t[k<<1|1].s[i];
t[k<<1|1].s[i]=0;
}
t[k<<1].lazy|=t[k].lazy;
t[k<<1|1].lazy|=t[k].lazy;
t[k].lazy=0;
}
}
void push_up(int k)
{
if(t[k].l!=t[k].r)
{
for(int i=0; i<8; i++)
{
t[k].s[i]=t[k<<1].s[i]+t[k<<1|1].s[i];
}
}
}
void build(int l,int r,int k)
{
t[k].l=l;
t[k].r=r;
t[k].sum=0;
for(int i=0; i<8; i++)t[k].s[i]=0;
t[k].s[0]=t[k].r-t[k].l+1;
t[k].lazy=0;
t[k].lazy2=0;
if(l==r)
{
return ;
}
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
push_up(k);
}
void update(int l,int r,int k,int type,int val)
{
if(r<t[k].l||l>t[k].r)return ;
push_down(k);
if(l<=t[k].l&&t[k].r<=r)
{
if(val==1)
{
t[k].lazy=type;
for(int i=7; i>=0; i--)
{
if((i|type)==i)continue;
t[k].s[i|type]+=t[k].s[i];
t[k].s[i]=0;
}
}
else
{
t[k].lazy2=1;
for(int i=0; i<8; i++)t[k].s[i]=0;
t[k].s[0]=t[k].r-t[k].l+1;
}
push_down(k);
return ;
}
update(l,r,k<<1,type,val);
update(l,r,k<<1|1,type,val);
push_up(k);
}
int querysum(int l,int r,int k)
{
if(r<t[k].l||l>t[k].r)return 0;
push_down(k);
if(l<=t[k].l&&t[k].r<=r)
{
return t[k].s[7];
}
int ans=0;
ans+=querysum(l,r,k<<1);
ans+=querysum(l,r,k<<1|1);
return ans;
}
int na,nb,nc;
int n,q;
signed main()
{
int tt;
read(tt);
int cas=0;
while(tt--)
{
cas++;
clk=0;
read(n,q);
for(int i=2; i<=n; i++)
{
int x;
read(x);
g[x].pb(i);
g[i].pb(x);
}
dfs(1,0);
dfs2(1,0);
build(1,n,1);
while(q--)
{
read(na,nb,nc);
for(int i=1; i<=na; i++)
{
read(a[i]);
int x=1,y=a[i];
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(dfn[top[x]],dfn[x],1,1,1);
x=fa[top[x]];
}
if(dfn[x]<dfn[y]) swap(x,y);
update(dfn[y],dfn[x],1,1,1);
}
for(int i=1; i<=nb; i++)
{
read(b[i]);
int x=1,y=b[i];
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(dfn[top[x]],dfn[x],1,2,1);
x=fa[top[x]];
}
if(dfn[x]<dfn[y]) swap(x,y);
update(dfn[y],dfn[x],1,2,1);
}
for(int i=1; i<=nc; i++)
{
read(c[i]);
int x=c[i];
update(dfn[x],out[x],1,4,1);
}
int ans=querysum(1,out[1],1);
write(ans);
printf("\n");
update(1,out[1],1,1,-1);
}
build(1,n,1);
for(int i=0; i<=n+2; i++)
{
g[i].clear();
a[i]=b[i]=c[i]=son[i]=siz[i]=fa[i]=0;
dep[i]=top[i]=dfn[i]=rk[i]=clk=out[i]=0;
}
}
}
边栏推荐
- Sweet butter
- 1. Excel的IF函数
- How to choose the key words of the thesis?
- mongoDB为什么快
- Recommendation | scholar's art and Tao: writing papers is a skill
- Wu Enda's machine learning after class exercises - linear regression
- How does win11 set the theme color of the status bar? Win11 method of setting theme color of status bar
- I.MX6U-ALPHA开发板(GPIO中断实验)
- UE4 获取玩家控制权的两种方式
- [learning notes] agc041
猜你喜欢

When you try to delete all bad code in the program | daily anecdotes

Chapter 3 how to use sourcetree to submit code

1. Excel的IF函数

Recommendation Book Educational Psychology: a book for tomorrow's teachers~

Li Kou daily question - day 42 -661. Picture smoother

How does win11 set the theme color of the status bar? Win11 method of setting theme color of status bar

FFmpeg 视频编码

idea插件离线安装(持续更新)

低成本、快速、高效搭建数字藏品APP、H5系统,扇贝科技专业开发更放心!

性能和成本的综合架构:单元化架构
随机推荐
机器学习之桑基图(用于用户行为分析)
Postman imports curl, exports curl, and exports corresponding language codes
Function knowledge points
Analyzing the curriculum design evaluation system of steam Education
生活相关——十年的职业历程(转)
Scroll view pull-down refresh and pull-up load (bottom)
生活相关——一个华科研究生导师的肺腑之言(主要适用于理工科)
idea插件离线安装(持续更新)
【学习笔记】AGC041
Threadpooltaskexecutor and ThreadPoolExecutor
Soft simulation rasterization renderer
How to write the introduction and conclusion of an overview paper?
数组排序3
1. Mx6u-alpha development board (GPIO interrupt experiment)
生活相关——减少期待,更快乐
建设面向青少年的创客教育实验室
使用百度飞桨EasyDL完成垃圾分类
How to choose the key words of the thesis?
Sangi diagram of machine learning (for user behavior analysis)
The difference between positive samples, negative samples, simple samples and difficult samples in deep learning (simple and easy to understand)