社区讨论
关于一 种错误的点分治写法是否能被卡掉
学术版参与者 3已保存回复 6
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @lochntlk
- 此快照首次捕获于
- 2023/10/30 13:58 2 年前
- 此快照最后确认于
- 2023/11/05 01:24 2 年前
今天发现之前我的点分治板子一直有点问题.把重心提出来之后他剩下每个子树的正常应该重新求一遍,我还是直接用的求重心的时候的。这种找法会导致一个子树求错
理论上来讲复杂度应该会出现问题,但我这个板子从来没有被卡过。
请问是数据过水,还是这种做法本来复杂度就不会退化太多?
CPP#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;
}
回复
共 6 条回复,欢迎继续交流。
正在加载回复...