poj 神秘 TLE 求差错
  • 板块学术版
  • 楼主ShanQing
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/11/10 16:32
  • 上次更新2024/11/10 16:34:00
查看原帖
poj 神秘 TLE 求差错
368204
ShanQing楼主2024/11/10 16:32

有一道众所周知的典是 P4178/poj1741 Tree。

同样的代码,改了输入和 k 范围放洛谷能过,且每个点没跑超过 50ms,放 poj 直接 T 飞。各种改输入卡常均无效。

不知道是 poj 数据比洛谷强还是 C++98 相关的问题。

#include <iostream>
#include <cstdio>
#include <vector>
//#include <windows.h>
#define ED cerr<<endl;
#define TS cerr<<"I AK IOI"<<endl;
#define cr(x) cerr<<x<<endl;
#define cr2(x,y) cerr<<x<<" "<<y<<endl;
#define cr3(x,y,z) cerr<<x<<" "<<y<<" "<<z<<endl;
#define cr4(x,y,z,w) cerr<<x<<" "<<y<<" "<<z<<" "<<w<<endl;
#define pii pair<int,int>
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ll long long
//#define ull unsigned long long
using namespace std;
const int N=4e4+5,M=1e7+5,INF=2e9,mod=1e9+7;
int n,k,ans=0;

struct edge {
	int ne,to,w;
	
	void read(int _ne,int _to,int _w) {
		ne=_ne,to=_to,w=_w;
	};
}e[N<<1];
int head[N],tot=0;
int sz[N],mx[N],vis[N],dis[N],sum=0,rt=0;
int all[N],s[N],t=0,t2=0;
int tr[M];

void update(int u,int x) {
	for(int i=u;i<=k+1;i+=i&(-i)) tr[i]+=x;
}

int query(int u) {
	int res=0;
	for(int i=u;i!=0;i-=i&(-i)) res+=tr[i];
	return res;
}

void add(int u,int v,int w) {
	e[++tot].read(head[u],v,w);
	head[u]=tot;
}

void getrt(int u,int fa) {
	sz[u]=1,mx[u]=0;
	//cr2(u,fa)
	for(int i=head[u];i;i=e[i].ne) {
		int to=e[i].to;
		if(vis[to]||to==fa) continue;
		getrt(to,u),sz[u]+=sz[to];
		mx[u]=max(mx[u],sz[to]);
	}
	mx[u]=max(mx[u],sum-sz[u]);
	if(mx[u]<mx[rt]) rt=u;
}

void getdis(int u,int fa) {
	if(dis[u]>k) return;
	s[++t]=dis[u];
	for(int i=head[u];i;i=e[i].ne) {
		int to=e[i].to;
		if(vis[to]||to==fa) continue;
		dis[to]=dis[u]+e[i].w,getdis(to,u);
	}
}

void work(int u) {
	t2=0;
	for(int i=head[u];i;i=e[i].ne) {
		int to=e[i].to;
		if(vis[to]) continue;
		t=0,dis[to]=e[i].w,getdis(to,u);
		for(int j=1;j<=t;++j) ans+=query(k-s[j]+1)+1;
		for(int j=1;j<=t;++j) update(s[j]+1,1);
		for(int j=1;j<=t;++j) all[++t2]=s[j];
	}
	for(int i=1;i<=t2;++i) update(all[i]+1,-1);
}

void solve(int u) {
	vis[u]=1,work(u);
	for(int i=head[u];i;i=e[i].ne) {
		int to=e[i].to;
		if(vis[to]) continue;
		sum=sz[to],mx[rt=0]=INF;
		getrt(to,-1),getrt(rt,-1); 
		solve(to); 
	}
}

void Main() {
	int u,v,w;ans=tot=0;
	for(int i=1;i<=n;++i) {
		vis[i]=head[i]=0;
	}
	//TS
	for(int i=1;i<=n-1;++i) {
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w),add(v,u,w);
	}
	if(k>M-3) {
		printf("%d\n",n*(n-1)/2);
		return;
	}
	//TS
	mx[rt=0]=INF,sum=n;
	getrt(1,-1),getrt(rt,-1);
	solve(rt);
	printf("%d\n",ans);
}

int main()
{
	//freopen("qwq.in","r",stdin);
	//ios::sync_with_stdio(false);
	//cin.tie(0),cout.tie(0);
	while(scanf("%d%d",&n,&k)) {
		if(!n&&!k) break; 
		Main();
	}
	return 0;
}

2024/11/10 16:32
加载中...