点分治 为什么没离线处理就会WA
查看原帖
点分治 为什么没离线处理就会WA
1420058
HaloisAWA楼主2024/11/11 09:15

这个是离线处理的

#include<bits/stdc++.h>
using namespace std;
struct node{
	int v,w;
	node(int vv,int ww) {
		v = vv;
		w = ww;
		return;
	}
};
int n,m,ut,vt,wt,k;
long long dp[40010],dis[40010],maxn;
vector<node> g[40010];
vector<pair<long long,int> > d;
vector<int> query;
bool ans[40010];
bool vis[40010],flag;
int center,l,r,cnt;
void dfs1(int u,int fa) {
	long long tmp = 0;
	dp[u] = 1;
	for (int i = 0;i < g[u].size();i ++) {
		int v = g[u][i].v,w = g[u][i].w;
		if (v != fa && (!vis[v])) {
			dfs1(v,u);
			dp[u] += dp[v];
			tmp = max(tmp,dp[v]);
		}
	}
	tmp = max(tmp,cnt - dp[u]);//////
	if (tmp < maxn) {
		center = u;
		maxn = tmp;
	}
	return;
}
void dfs2(int u,int fa,int colr) {
	d.push_back(make_pair(dis[u],colr));//放在这里是为了保证根节点进入vector 
	for (int i = 0;i < g[u].size();i ++) {
		int v = g[u][i].v,w = g[u][i].w;
		if (v != fa && (!vis[v])) {
			dis[v] = dis[u] + w;//这句话放在dfs2前面 
			dfs2(v,u,colr);
		}
	}
	return;
}
void calc(int u) {
	dis[u] = 0;//
	d.clear();//
	
	d.push_back(make_pair(dis[u],u));
	for (int i = 0;i < g[u].size();i ++) {
		int v = g[u][i].v,w = g[u][i].w;
		if (!vis[v]) {
			dis[v] = dis[u] + w;
			dfs2(v,u,v);
		}
	}
	
	sort(d.begin(),d.end());//
	for (int i = 1;i <= m;i ++) {
		if (ans[i]) {
			//printf("-----\n");
			continue;
		}
		l = 0;
		r = d.size() - 1;
		int val = query[i - 1];
		while (l < r) {
			if (d[l].first + d[r].first == val) {
				if (d[l].second != d[r].second) { 
					ans[i] = true;
					break;
				} else {
					++ l;
				}
			} else if (d[l].first + d[r].first < val) ++ l;
			else -- r;
		}
	}
	return;
}
void solve(int u) {
	vis[u] = true;
	calc(u);
	for (int i = 0;i < g[u].size();i ++) {
		int v = g[u][i].v,w = g[u][i].w;
		if (!vis[v]) {
			cnt = dp[v];//
			maxn = 0x7fffffff;//
			dfs1(v,0);
			solve(center);
		}
	}
	return;
}
int main() {
	scanf("%d%d",&n,&m);
	for (int i = 1;i < n;i ++) {
		scanf("%d%d%d",&ut,&vt,&wt);
		g[ut].push_back(node(vt,wt));
		g[vt].push_back(node(ut,wt));
	}
	for (int kkk = 1;kkk <= m;kkk ++) {
		scanf("%d",&k);
		query.push_back(k);
	}
	maxn = 0x7fffffff;
	cnt = n;
	flag = false;
	dfs1(1,0);//找重心 
	//dis[center] = 0;
	solve(center);
	for (int i = 1;i <= m;i ++)
		if (ans[i]) printf("AYE\n");
		else printf("NAY\n");
	return 0;
}

这个是没有离线处理的

#include<bits/stdc++.h>
using namespace std;
struct node{
	int v,w;
	node(int vv,int ww) {
		v = vv;
		w = ww;
		return;
	}
};
int n,m,ut,vt,wt,k;
long long dp[40010],dis[40010],maxn,ans;
vector<node> g[40010];
vector<pair<long long,int> > d;
vector<int> query;
bool vis[40010],flag;
int center,l,r,cnt;
void dfs1(int u,int fa) {
	long long tmp = 0;
	dp[u] = 1;
	for (int i = 0;i < g[u].size();i ++) {
		int v = g[u][i].v,w = g[u][i].w;
		if (v != fa && (!vis[v])) {
			dfs1(v,u);
			dp[u] += dp[v];
			tmp = max(tmp,dp[v]);
		}
	}
	tmp = max(tmp,cnt - dp[u]);//////
	if (tmp < maxn) {
		center = u;
		maxn = tmp;
	}
	return;
}
void dfs2(int u,int fa,int colr) {
	d.push_back(make_pair(dis[u],colr));//放在这里是为了保证根节点进入vector 
	for (int i = 0;i < g[u].size();i ++) {
		int v = g[u][i].v,w = g[u][i].w;
		if (v != fa && (!vis[v])) {
			dis[v] = dis[u] + w;//这句话放在dfs2前面 
			dfs2(v,u,colr);
		}
	}
	return;
}
void calc(int u,int val) {
	dis[u] = 0;//
	d.clear();//
	
	d.push_back(make_pair(dis[u],u));
	for (int i = 0;i < g[u].size();i ++) {
		int v = g[u][i].v,w = g[u][i].w;
		if (!vis[v]) {
			dis[v] = dis[u] + w;
			dfs2(v,u,v);
		}
	}
	
	sort(d.begin(),d.end());//
	l = 0;
	r = d.size() - 1;
	while (l < r) {
		if (d[l].first + d[r].first == val) {
			if (d[l].second != d[r].second) { 
				printf("AYE\n");
				return;
			} else {
				++ l;
			}
		} else if (d[l].first + d[r].first < val) ++ l;
		else -- r;
	}
	return;
}
void solve(int u) {
	vis[u] = true;
	calc(u,k);
	for (int i = 0;i < g[u].size();i ++) {
		int v = g[u][i].v,w = g[u][i].w;
		if (!vis[v]) {
			cnt = dp[v];//
			maxn = 0x7fffffff;//
			dfs1(v,0);
			solve(center);
		}
	}
	return;
}
int main() {
	scanf("%d%d",&n,&m);
	for (int i = 1;i < n;i ++) {
		scanf("%d%d%d",&ut,&vt,&wt);
		g[ut].push_back(node(vt,wt));
		g[vt].push_back(node(ut,wt));
	}
	for (int kkk = 1;kkk <= m;kkk ++) {
		scanf("%d",&k);
	maxn = 0x7fffffff;
	cnt = n;
	flag = false;
	dfs1(1,0);//找重心 
	//dis[center] = 0;
	solve(center);
	if (!flag) printf("NAY\n");
		//query.push_back(k);
	}
	
	return 0;
}

2024/11/11 09:15
加载中...