P3899 [湖南集训] 更为厉害

题意

请自行移步洛谷

分析

每次询问有两种情况:

  • a 为 (a,b,c) 中深度第二大的节点,即 b 在 a 到根的路径上 (不含 a )。

对答案的贡献即为 (siza1)min(depa1,k)

  • a 为 (a,b,c) 中深度最小的节点,即 b 是 a 的儿子。

sona,d 为 a 点的 d 级儿子,此处的 d 级儿子是指在 a 子树内并且深度差等于 d 的点。

对答案的贡献即为 d=1kusona,dsizu

所以得出,维护第二种情况较为困难。但是这是可以解决的,将子树大小记在对应深度的线段树的节点上,遍历时向上线段树合并即可。


codes

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+100;
typedef long long ll;
inline int read()
{
register char c=getchar();int x=0;
while(!isdigit(c))c=getchar();
while(isdigit(c)){x=(x<<1)+(x<<3)+c-48;c=getchar();}
return x;
}
struct edge{int y,n;}e[N<<1];
struct ques
{
int id;
int x;
}g[N];
int n,q,head[N],cnt;
int siz[N],dep[N],deg[N];
ll ans[N];
vector<ques>h[N];
struct segtree
{
struct node{ll val;int lc,rc;}s[N<<5];
int tot,root[N<<5];
void pushup(int i){s[i].val=s[ s[i].lc ].val+s[ s[i].rc ].val;}
void upd(int &i,int l,int r,int x,ll z)
{
if(!i)i=++tot;
s[i].val+=z;
if(l==r)
return ;
int mid=(l+r)>>1;
if(x<=mid)upd(s[i].lc,l,mid,x,z);
else upd(s[i].rc,mid+1,r,x,z);
pushup(i);
}
void merg(int &i,int &j,int l,int r)// i <-- j
{
if(!i || !j)
{
i+=j;
return ;
}
if(l==r){s[i].val+=s[j].val;return ;}
int mid=(l+r)>>1;
merg(s[i].lc,s[j].lc,l,mid);
merg(s[i].rc,s[j].rc,mid+1,r);
pushup(i);
}
ll que(int i,int l,int r,int x,int y)
{
if(!i)return 0;
if(l>=x && r<=y)return s[i].val;
int mid=(l+r)>>1;ll sum=0;
if(x<=mid)sum+=que(s[i].lc,l,mid,x,y);
if(y>mid)sum+=que(s[i].rc,mid+1,r,x,y);
return sum;
}
void modi(int u){upd(root[u],1,n,dep[u],siz[u]-1);}
void mer(int x,int y){merg(root[x],root[y],1,n);}
ll ask(int x,int y)
{
if(dep[x]==n)return 0;
return que(root[x],1,n,dep[x]+1,min(dep[x]+y,n));
}
}T;
void ad(int x,int y)
{
e[++cnt].n=head[x];
e[cnt].y=y;head[x]=cnt;
}
void loading(int u,int fa)
{
siz[u]=1;dep[u]=dep[fa]+1;
for(int i=head[u],v;i;i=e[i].n)
{
v=e[i].y;
if(v==fa)continue;
loading(v,u);
siz[u]+=siz[v];
}
T.modi(u);
}
void init()
{
n=read();q=read();
for(int i=1,x,y;i<n;++i)
{
x=read();y=read();
ad(x,y);ad(y,x);
}
loading(1,0);
ques node;
for(int i=1,x,y;i<=q;++i)
{
x=read();
y=read();
node.id=i;
node.x=y;
++deg[x];
h[x].push_back(node);
}
}
void collect(int u,int fa)
{
for(int i=head[u],v;i;i=e[i].n)
{
v=e[i].y;
if(v==fa)continue;
collect(v,u);
T.mer(u,v);
}
for(int i=0;i<deg[u];++i)
{
int id=h[u][i].id;ll nw=h[u][i].x;
ans[id]+=(siz[u]-1ll)*min(dep[u]-1ll,nw);
ans[id]+=(T.ask(u,nw));
}
}
void work()
{
collect(1,0);
for(int i=1;i<=q;++i)printf("%lld\n",ans[i]);
}
int main()
{
init();
work();
return 0;
}
posted @   Glowingfire  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示