站外题求助
  • 板块灌水区
  • 楼主Wenzhou_wwx
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/9/15 14:34
  • 上次更新2023/11/2 20:46:25
查看原帖
站外题求助
410209
Wenzhou_wwx楼主2023/9/15 14:34

如题,loj6046,TLE,看了几篇题解都不知道哪里有问题,似乎复杂度假了

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<cstring>
#include<cmath>
#include<vector>
const int N=100001,B=320,inf=0x7fffffff;
int n,m,len,blo,maxd,idx,dfn[N],sz[N],dep[N],a[N],cnt,bel[N],st[B],ed[B],add[B],up[B],down[B],sum[B][10*B];
std::vector<std::pair<int,int>>g[N];
inline void dfs(int u)
{
	dfn[u]=++idx,sz[u]=1;
	for(const auto&[v,w]:g[u])dep[v]=dep[u]+w,maxd=std::max(maxd,dep[v]),dfs(v),sz[u]+=sz[v];
}
inline void update(int x)
{
	up[x]=-inf,down[x]=inf;
	for(int i=st[x];i<=ed[x];++i)bel[i]=x,up[x]=std::max(up[x],a[i]),down[x]=std::min(down[x],a[i]);
	memset(sum[x],0,sizeof(int)*(up[x]-down[x]+1));
	for(int i=st[x];i<=ed[x];++i)++sum[x][a[i]-down[x]];
	for(int i=1;i<=up[x]-down[x];++i)sum[x][i]+=sum[x][i-1];
}
inline void build()
{
	for(int i=1;i<=n;++i)a[i]+=add[bel[i]];
	memset(add,0,sizeof(int)*(cnt+1)),cnt=0;
	for(int i=1,j=1,min=a[1],max=a[1];i<=n;++i){
		min=std::min(min,a[i+1]),max=std::max(max,a[i+1]);
		if(max-min+1>=len*blo||i-j+1>=blo||i==n)st[++cnt]=j,ed[cnt]=i,update(cnt),j=i+1,min=max=a[i+1];
	}
}
inline void modify(int l,int r,int k)
{
	for(;l<=r;l=ed[bel[l]]+1)
	if(l==st[bel[l]]&&ed[bel[l]]<=r)add[bel[l]]+=k,up[bel[l]]+=k,down[bel[l]]+=k;
	else{
		for(int i=l;i<=r&&i<=ed[bel[l]];++i)a[i]+=k;
		for(int i=st[bel[l]];i<=ed[bel[l]];++i)a[i]+=add[bel[l]];
		add[bel[l]]=0,update(bel[l]);
	}
}
inline int query(int l,int r,int k)
{
	int res=0;
	for(;l<=r;l=ed[bel[l]]+1)
	if(l==st[bel[l]]&&ed[bel[l]]<=r)res+=k>=up[bel[l]]?ed[bel[l]]-st[bel[l]]+1:(k>=down[bel[l]]?sum[bel[l]][k-down[bel[l]]]:0);
	else{
		for(int i=st[bel[l]];i<=ed[bel[l]];++i)a[i]+=add[bel[l]];
		add[bel[l]]=0;
		for(int i=l;i<=r&&i<=ed[bel[l]];++i)res+=a[i]<=k;
	}
	return res;
}
int main()
{
	freopen("j11.in","r",stdin);
	freopen("ye.out","w",stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr),std::cout.tie(nullptr);
	std::cin>>n>>m>>len,blo=sqrt(n);
	for(int i=2,x,k;i<=n;++i)std::cin>>x>>k,g[x].emplace_back(i,k);
	dfs(1);
	for(int i=1;i<=n;++i)a[dfn[i]]=dep[i];
	build();
	for(int opt,x,k,tot=0;m--;)
	if(std::cin>>opt>>x>>k,opt==1){
		if(sz[x]<k)std::cout<<-1<<'\n';
		else{
			int l=0,r=maxd,mid,res=0;
			while(l<=r){
				mid=(l+r)>>1;
				if(query(dfn[x],dfn[x]+sz[x]-1,mid)>=k)res=mid,r=mid-1;
				else l=mid+1;
			}
			std::cout<<res<<'\n';
		}
	}
	else{
		maxd+=k,modify(dfn[x],dfn[x]+sz[x]-1,k),++tot;
		if(tot==1500)build(),tot=0;
	}
	return 0;
}
2023/9/15 14:34
加载中...