求证伪复杂度
查看原帖
求证伪复杂度
856004
Grammar_hbw楼主2024/12/3 17:58

一直TLE on 12……

#include <bits/stdc++.h>
#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
const int N=1000007;
struct segtree{
	int val[N*4],ls[N*4],rs[N*4],cnt=0;
	int newnode(){
		int o=(++cnt);
		val[o]=ls[o]=rs[o]=0;
		return o;
	}
	void update(int o){val[o]=val[ls[o]]+val[rs[o]];}
	void add(int x,int l,int r,int o,int v){
		assert(x>=0);
		assert(x<N);
		if(l==r) return void(val[o]+=v);
		int mid=(l+r)>>1;
		if(x<=mid) add(x,l,mid,ls[o]?ls[o]:(ls[o]=newnode()),v);
		else add(x,mid+1,r,rs[o]?rs[o]:(rs[o]=newnode()),v);
		update(o);
	}
	int query(int l,int r,int ll,int rr,int o){
		if(l<=ll&&rr<=r) return val[o];
		if(l>r) return 0;
		if(!o) return 0;
		int mid=(ll+rr)>>1,ans=0;
		if(l<=mid) ans+=query(l,r,ll,mid,ls[o]);
		if(r>mid) ans+=query(l,r,mid+1,rr,rs[o]);
		return ans;
	}
	int lower_bound(int ll,int rr,int o,int v){
		if(val[o]<v) return -1;
		if(ll==rr) return ll;
		int mid=(ll+rr)>>1;
		if(val[ls[o]]>=v) return lower_bound(ll,mid,ls[o],v);
		else return lower_bound(mid+1,rr,rs[o],v-val[ls[o]]);
	}
} tr;
struct query{int t,l,k;}; vector<query> q[N];
vector<int> to[N];
set<int> s[N];
int a[N],p[N],c[N],ans[N],n,qq;
void dfs(int now){
	s[c[a[now]]].erase(a[now]);
	s[c[a[now]]+1].insert(a[now]);
	tr.add(c[a[now]],0,n,1,-1);
	tr.add(c[a[now]]+1,0,n,1,1);
	c[a[now]]++;
	for(auto i:q[now]){
		int t=i.t,l=i.l,k=i.k;
		int sum=tr.lower_bound(0,n,1,k+tr.query(0,l-1,0,n,1));
		if(sum>0) ans[t]=*s[sum].begin();
		else ans[t]=-1;
	}
	for(auto i:to[now]) dfs(i);
	s[c[a[now]]].erase(a[now]);
	s[c[a[now]]-1].insert(a[now]);
	tr.add(c[a[now]],0,n,1,-1);
	tr.add(c[a[now]]-1,0,n,1,1);
	c[a[now]]--;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	for(int i=1;i<N;i++) s[0].insert(i);
	int t;
	cin>>t;
	while(t-->0){
		cin>>n>>qq;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=2;i<=n;i++) cin>>p[i],to[p[i]].push_back(i);
		for(int i=1,v,l,k;i<=qq;i++) cin>>v>>l>>k,q[v].push_back({i,l,k});
		tr.cnt=0;
		tr.add(0,0,n,tr.newnode(),n);
		dfs(1);
		for(int i=1;i<=qq;i++) cout<<ans[i]<<" \n"[i==qq];
		for(int i=1;i<=n;i++) q[i].clear(),to[i].clear(),c[i]=0;
	}
}
2024/12/3 17:58
加载中...