线段树合并求卡常
查看原帖
线段树合并求卡常
723198
AAA404楼主2025/1/5 00:14

rt,自认为码风良好,TLE 70。

#include<bits/stdc++.h>
#pragma target("avx512f,sse2,sse3,sse4,sse4.2")
using namespace std;
const int N=1e6+5;
int n,q,cnt,ls[N*40],rs[N*40],sz[N],dep[N],root[N],sum[N*40],ans[N];
vector<int>v[N];
vector<pair<int,int> >g[N];
void insert(int &rt,int l,int r,int p,int k)
{
	if(!rt)rt=++cnt;
	if(l==r){sum[rt]+=k;return;}
	int mid=l+r>>1;
	if(p<=mid)insert(ls[rt],l,mid,p,k);
	else insert(rs[rt],mid+1,r,p,k);
	sum[rt]=sum[ls[rt]]+sum[rs[rt]];
}
int merge(int x,int y,int l,int r)
{
	if(!x||!y)return x+y;
	if(l==r){sum[x]+=sum[y];return x;}
	int mid=l+r>>1;
	ls[x]=merge(ls[x],ls[y],l,mid);
	rs[x]=merge(rs[x],rs[y],mid+1,r);
	sum[x]=sum[ls[x]]+sum[rs[x]];
	return x;
}
int query(int rt,int l,int r,int a,int b)
{
	if(!rt||a>b)return 0;
	if(l==r)return sum[rt];
	int mid=l+r>>1,ans=0;
	if(a<=mid)ans+=query(ls[rt],l,mid,a,b);
	if(b>mid)ans+=query(rs[rt],mid+1,r,a,b);
	return ans;
}
void dfs(int p,int faa)
{
	sz[p]=1;
	dep[p]=dep[faa]+1;
	for(int t:v[p])
	{
		if(t==faa)continue;
		dfs(t,p);
		root[p]=merge(root[p],root[t],1,n);
		sz[p]+=sz[t];
	}
	insert(root[p],1,n,dep[p],sz[p]-1);
	for(auto t:g[p])
		ans[t.second]=query(root[p],1,n,dep[p]+1,dep[p]+t.first)+1ll*min(t.first,dep[p]-1)*(sz[p]-1);
	return;
}
char *p1,*p2,buf[10000005];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,10000000,stdin),p1==p2)?EOF:*p1++)
int read(){
int x=0,f=1;char ch=nc();
while(ch<48||ch>57){if(ch=='-')f=-1;ch=nc();}
while(ch>=48&&ch<=57){x=x*10+ch-48,ch=nc();}
return x*f;
}
int main()
{
    // ios::sync_with_stdio(0);
 	// cin.tie(0);cout.tie(0);
	n=read(),q=read();
	for(int i=1;i<=n-1;i++)
	{
		int a=read(),b=read();
		v[a].push_back(b);
		v[b].push_back(a);
	}
	for(int i=1;i<=q;i++)
	{
		int p=read(),k=read();
		g[p].push_back(make_pair(k,i));
	}
	dfs(1,0);
	for(int i=1;i<=q;i++)printf("%d\n",ans[i]);
 	return 0;
}
2025/1/5 00:14
加载中...