关于一 种错误的点分治写法是否能被卡掉
  • 板块学术版
  • 楼主_gjm2005_
  • 当前回复6
  • 已保存回复6
  • 发布时间2021/3/29 11:54
  • 上次更新2023/11/5 01:24:44
查看原帖
关于一 种错误的点分治写法是否能被卡掉
93382
_gjm2005_楼主2021/3/29 11:54

今天发现之前我的点分治板子一直有点问题.把重心提出来之后他剩下每个子树的sizesize正常应该重新求一遍,我还是直接用的求重心的时候的sizesize。这种找法会导致一个子树sizesize求错

理论上来讲复杂度应该会出现问题,但我这个板子从来没有被卡过。

请问是数据过水,还是这种做法本来复杂度就不会退化太多?

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

#define FOR(i,a,b) for(int i = a; i <= b; ++i)
#define _FOR(i,a,b) for(int i = a; i >= b; --i)
#define gjm(i,x) for(int i = head[x]; i; i = e[i].next)

template<typename T>void read(T &x)
{
	x = 0;int f = 1;
	char c = getchar();
	for(;!isdigit(c);c = getchar()) if(c == '-') f = -1;
	for(;isdigit(c);c = getchar()) x = x * 10 + c - '0';
	x *= f;
}

struct edge
{
	int to,next,val;
} e[N << 1];

bool vis[N];
int n,K,rt,min_size,sum;
int head[N],qaq[N],cnt,size[N],dis[N],ans;

void add(int x,int y,int z)
{
	e[++cnt] = (edge){y,head[x],z};
	head[x] = cnt;
}

void getrt(int x,int fa)
{
	int tmp = 0;
	size[x] = 1;
	gjm(i,x)
	{
		int y = e[i].to;
		if(y == fa || vis[y]) continue;
		getrt(y,x);
		size[x] += size[y],tmp = max(tmp,size[y]);
	}
	tmp = max(tmp,sum - size[x]);
	if(tmp < min_size) min_size = tmp,rt = x;
}

void getdis(int x,int fa)
{
	qaq[++qaq[0]] = dis[x];
	gjm(i,x)
	{
		int y = e[i].to;
		if(y == fa || vis[y]) continue;
		dis[y] = dis[x] + e[i].val;
		getdis(y,x);
	}
}

int jisuan(int x,int val)
{
	dis[x] = val,qaq[0] = 0;getdis(x,0);
	sort(qaq + 1,qaq + qaq[0] + 1);
	int l = 1,r = qaq[0],anss = 0;
	while(l <= r)
	{
		if(qaq[l] + qaq[r] <= K) anss += r - l,++l;
		else --r;
	}
	l = 1,r = qaq[0];
	while(l <= r)
	{
		if(qaq[l] + qaq[r] < K) anss -= r - l,++l;
		else --r;
	}
	return anss;
}

void dfs(int x)
{
	vis[x] = 1;ans += jisuan(x,0);
	gjm(i,x)
	{
		int y = e[i].to;
		if(vis[y]) continue;
		ans -= jisuan(y,e[i].val);
		sum = size[y],min_size = INT_MAX;
		getrt(y,x),dfs(rt);
	}
}

int main() 
{

	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
	int m;
	read(n),read(m);
	FOR(i,1,n - 1)
	{
		int x,y,z;
		read(x),read(y),read(z);
		add(x,y,z),add(y,x,z);
	}
	while(m--)
	{
		memset(vis,0,sizeof(vis));
		ans = 0,read(K);
		sum = n,min_size = INT_MAX,getrt(1,0);
		dfs(rt);
		if(ans == 0) puts("NAY");
		else puts("AYE");
	}
	return 0;
}

2021/3/29 11:54
加载中...