题目是bzoj4771,思路是这个,调了一整天了,发现是merge产生了过多节点,下面是代码。
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int __x=0,__f=1;
char __c=getchar();
while(__c<'0'||__c>'9') {
if(__c=='-')__f=-1;
__c=getchar();
}
while(__c>='0'&&__c<='9') {
__x=__x*10+__c-'0';
__c=getchar();
}
return __x*__f;
}
char __F[200];
inline void write(int __x) {
if(__x<0) {
putchar('-');
__x=-__x;
}
if(__x>=10)write(__x/10);
putchar(__x%10+'0');
}
const int maxn=1e5+5;
struct edge {
int next,to;
} e[maxn*2];
int T,n,m,a[maxn],h[maxn],cnt,lst,rt[maxn],rt2[maxn],d[maxn],delrt,maxd,shik,sk2;
void addedge(int x,int y) {
e[++cnt].next=h[x];
e[cnt].to=y;
h[x]=cnt;
}
namespace tree1 {
#define lc(x) t[x].l
#define rc(x) t[x].r
struct tree {
int l,r,sum;
} t[maxn*1000];
int tot;
void pushup(int id) {
t[id].sum=t[lc(id)].sum+t[rc(id)].sum;
}
int merge(int a,int b,int l,int r) {
if(!a||!b)return a+b;
int w=++tot;
//shik++;
if(l==r) {
t[w].sum=t[a].sum+t[b].sum;
return w;
}
int mid=(l+r)/2;
lc(w)=merge(lc(a),lc(b),l,mid);
rc(w)=merge(rc(a),rc(b),mid+1,r);
pushup(w);
return w;
}
void add(int &id,int l,int r,int v,int k) {
if(!id)id=++tot;
//cout<<l<<' '<<r<<' '<<v<<' '<<k<<'*'<<endl;
if(l==r) {
t[id].sum+=k;
return;
}
int mid=(l+r)/2;
v<=mid?add(lc(id),l,mid,v,k):add(rc(id),mid+1,r,v,k);
pushup(id);
}
int ask(int id,int l,int r,int L,int R) {
//cout<<id<<' '<<l<<' '<<r<<' '<<L<<' '<<R<<' '<<t[id].sum<<endl;
if(!id)return 0;
if(L<=l&&R>=r)return t[id].sum;
int ans=0,mid=(l+r)/2;
if(L<=mid)ans+=ask(lc(id),l,mid,L,R);
if(R>mid)ans+=ask(rc(id),mid+1,r,L,R);
return ans;
}
void dfscout(int id,int l,int r) {
if(!id)return;
cout<<id<<' '<<l<<' '<<r<<' '<<t[id].sum<<endl;
if(l==r)return;
int mid=(l+r)/2;
dfscout(lc(id),l,mid),dfscout(rc(id),mid+1,r);
}
#undef lc
#undef rc
}
namespace tree2 {
#define lc(x) t[x].l
#define rc(x) t[x].r
struct tree {
int l,r,v;
} t[maxn*40];
int tot;
int merge(int a,int b,int l,int r) {
if(!a||!b)return a+b;
if(l==r) {
tree1::add(delrt,1,n,max(t[a].v,t[b].v),-1);
t[a].v=min(t[a].v,t[b].v);
return a;
}
int mid=(l+r)/2;
lc(a)=merge(lc(a),lc(b),l,mid);
rc(a)=merge(rc(a),rc(b),mid+1,r);
return a;
}
void add(int &id,int l,int r,int v,int k) {
if(!id)id=++tot;
//cout<<id<<' '<<l<<' '<<r<<' '<<v<<' '<<k<<' '<<u<<'*'<<endl;
if(l==r) {
t[id].v=k;
return;
}
int mid=(l+r)/2;
v<=mid?add(lc(id),l,mid,v,k):add(rc(id),mid+1,r,v,k);
}
#undef lc
#undef rc
}
void dfs(int u) {
//write(u),putchar('\n');
tree2::add(rt2[u],1,n,a[u],d[u]);
int ltt=tree1::tot;
tree1::add(rt[u],1,n,d[u],1);
delrt=0;
for(register int i=h[u]; i; i=e[i].next) {
int j=e[i].to;
d[j]=d[u]+1;
dfs(j);
rt2[u]=tree2::merge(rt2[u],rt2[j],1,n);
rt[u]=tree1::merge(rt[u],rt[j],1,n);
}
// puts("------");
// cout<<u<<endl;
rt[u]=tree1::merge(rt[u],delrt,1,n);
if(u%300==0)cout<<tree1::tot-ltt<<' '<<shik<<' '<<u<<endl;
// tree1::dfscout(rt[u],1,n);
}
int main() {
int x,y;
T=read();
while(T--) {
memset(rt,0,(n+1)*4);
memset(rt2,0,(n+1)*4);
memset(tree1::t,0,(tree1::tot+1)*sizeof(tree1::t[0]));
memset(tree2::t,0,(tree2::tot+1)*sizeof(tree2::t[0]));
memset(h,0,(n+1)*4);
tree1::tot=tree2::tot=cnt=lst=0;
n=read(),m=read();
for(register int i=1; i<=n; i++)a[i]=read();
for(register int i=2; i<=n; i++)x=read(),addedge(x,i);
dfs(1);
// for(register int i=1;i<=n;i++)puts("------"),cout<<i<<endl,tree1::dfscout(rt[i],1,n);
for(register int i=1; i<=m; i++) {
x=read(),y=read();
x^=lst,y^=lst;
// cout<<x<<' '<<y<<' ';
lst=tree1::ask(rt[x],1,maxd,d[x],d[x]+y);
write(lst),putchar('\n');
}
//exit(0);
}
return 0;
}