社区讨论

我是真的刚学C++

CF161DDistance in Tree参与者 12已保存回复 14

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
14 条
当前快照
1 份
快照标识符
@mi7x2w3g
此快照首次捕获于
2025/11/21 05:01
4 个月前
此快照最后确认于
2025/11/21 06:36
4 个月前
查看原帖
求助,写挂了,大佬别喷我
CPP
#include <cstdio>
#include <algorithm>
using std::sort;
const int maxn=1e5;
const int maxk=1e8;
template<class T>inline void read(T &x) {
	T f=1;x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=(x<<1)+(x<<3)+(s^48);s=getchar();}
	x*=f;
}
template<class T>inline T max(T a,T b) { return a>b?a:b; }
template<class T>inline T min(T a,T b) { return a<b?a:b; }
struct Edge {
	int u,v;
}e[maxn<<1];
int n,m,a,b,c,siz[maxn],maxs[maxn],Siz,root,cnt,tot,head[maxn<<1],vis[maxn],dis[maxn],k,ans;
bool cs[maxk];
inline void addedge(int u,int v) { e[++cnt].v=v; e[cnt].u=head[u]; head[u]=cnt; }
inline void add(int u,int v) { addedge(u,v); addedge(v,u); }
inline void getroot(int x,int fa) {
	siz[x]=1;maxs[x]=0;
	for(int i=head[x];i;i=e[i].u) {
		int v=e[i].v;
		if(v==fa||vis[v]) continue;
		getroot(v,x);
		siz[x]+=siz[v];
		maxs[x]=max(maxs[x],siz[v]);
	}
	maxs[x]=max(maxs[x],Siz-siz[x]);
	if(maxs[x]<maxs[root]) root=x;
}
inline int findl(int a,int b,int x) {
	int ans=0,l=a,r=b,mid;
	while(l<r) {
		mid=(l+r)>>1;
		if(dis[mid]<x) l=mid+1;
		else ans=mid,r=mid-1;
	}
	return ans;
}
inline int findr(int a,int b,int x) {
	int ans=0,l=a,r=b,mid;
	while(l<r) {
		mid=(l+r)>>1;
		if(dis[mid]<=x) l=mid+1;
		else ans=mid,r=mid-1;
	}
	return ans;
}
inline void getdis(int rt,int fa,int d) {
	int v;
	for(int i=head[rt];i;i=e[i].u) {
		v=e[i].v;
		if(v==fa||vis[v]) continue;
		dis[++tot]=d+1;
		getdis(v,rt,dis[tot]);
	}
}
inline int getans(int x,int d) {
	dis[tot=0]=d;
	getdis(x,0,d);
	sort(dis+1,dis+tot+1);
	//for(int i=1;i<=tot;i++) printf("%d ",dis[i]);
	int ll,rr,w=1,ans=0;
	while(w<tot&&dis[w]+dis[tot]<k) w++;
	while(w<tot&&dis[w]+dis[w+1]<k) {
		ll=findl(w+1,tot,k-dis[w]),rr=findr(w+1,tot,k-dis[w]);
		if(!ll&&!rr) ans+=(rr-ll+1);
		w++;
	}
	return ans;
}
inline void dfs(int x) {
	int v;vis[x]=0;
	ans+=getans(x,0);
	for(int i=head[x];i;i=e[i].u) {
		v=e[i].v;
		if(vis[v]) continue;
		ans-=getans(v,1);
		Siz=siz[v],root=0;
		getroot(v,x);
		dfs(root);
	}
}
int main() {
	read(n);read(k);
	for(int i=1;i<n;i++) read(a),read(b),add(a,b);
	dfs(root);
	printf("%d\n",ans);
}

回复

14 条回复,欢迎继续交流。

正在加载回复...