社区讨论

实在是走投无路了

学术版参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@lobotmy7
此快照首次捕获于
2023/10/30 00:30
2 年前
此快照最后确认于
2023/11/04 05:12
2 年前
查看原帖
POJ 2114,蜜汁TLE,调了三天了
只求大佬帮忙分析一下我的代码的复杂度,不胜感激!
CPP
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>

// set s.insert(x) , set s.find(x) set s.count(x)
using namespace std;

const int maxn = 1e4 + 5,maxm = 1e2 + 5;

struct node {
	int id,x;
	friend bool operator < (node a,node b) {
		return a.x < b.x;
	}
};

int first1[maxn << 1],last1[maxn << 1],dx1[maxn << 1],nxt1[maxn << 1],w1[maxn << 1],xb1; // for real
int first2[maxn << 1],last2[maxn << 1],dx2[maxn << 1],nxt2[maxn << 1],xb2; // for core

int n,x,y,minn,minid,sz[maxn],tot,rt,req[maxm],m,b[maxn],col[maxn];
bool used[maxn],ans[maxm];
multiset<node> v[maxn];

inline int read() {
	int x = 0,f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')
			f = -f;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar();
	}
	
	if (f > 0)
		return x; else
		return -x;
}

inline void init() {
	for (int i=0; i<=xb1; i++)
		first1[i] = nxt1[i] = 0;
	for (int i=0; i<=xb2; i++)
		first2[i] = nxt2[i] = 0;
	rt = xb1 = xb2 = m = x = y = tot = 0;
	for (int i=0; i <=n; i++) {
		v[i].clear();
		used[i] = 0;
	}
}

inline void build1(int x,int y,int z) {
	dx1[++xb1] = y,w1[xb1] = z;
	if (!first1[x])
		first1[x] = xb1; else
		nxt1[last1[x]] = xb1;
	last1[x] = xb1;	
}

inline void build2(int x,int y) {
	dx2[++xb2] = y;
	if (!first2[x])
		first2[x] = xb2; else
		nxt2[last2[x]] = xb2;
	last2[x] = xb2;	
}

inline void dfs_core1(int x,int fa) { //统计当前子树有多少个节点
	tot++;
	for (int i=first1[x]; i; i = nxt1[i]) {
		int y = dx1[i];
		if (used[y] || y == fa)
			continue;
		dfs_core1(y,x);
	}	
}

inline void dfs_core2(int x,int fa) { //确定该子树的重心
	int maxx = 0;
	sz[x] = 1;
	for (int i=first1[x]; i; i = nxt1[i]) {
		int y = dx1[i];
		if (used[y] || y == fa)
			continue;
		dfs_core2(y,x);
		maxx = max(maxx,sz[y]);
		sz[x] += sz[y];
	}
	
	maxx = max(maxx,tot - sz[x]);
	if (maxx < minn) {
		minn = maxx;
		minid = x;
	}
}

inline int get_core(int x) { // 寻找当前子树的重心
	minn = 1e9,tot = 0;
	dfs_core1(x,0);
	dfs_core2(x,0);
	return minid;
}

inline void dfs(int x,int fa) { //构建点分树
	int tmp = get_core(x);
	if (rt) {
		build2(fa,tmp);
		build2(tmp,fa);
	}
	if (!rt)
		rt = tmp;
	used[tmp] = 1;
	
	for (int i=first1[tmp]; i; i = nxt1[i]) {
		int y = dx1[i];
		if (used[y])
			continue;
		dfs(y,tmp);
	}
}
inline void get_number(int org,int x,int pre,int dis) { 
	v[org].insert((node){col[x],dis});

	for (int i=first1[x]; i; i = nxt1[i]) {
		int y = dx1[i];
		if (y == pre || used[y])
			continue;
		get_number(org,y,x,dis + w1[i]);
	}
}

void get_col(int x,int org,int pre) {
	col[x] = org;
	for (int i = first1[x]; i; i = nxt1[i]) {
		int y = dx1[i];
		if (y == pre || used[y])
			continue;
		get_col(y,org,x);
	}
}

inline void handle(int x,int fa) {
	used[x] = 1;
	
	for (int i=first2[x]; i; i = nxt2[i]) {
		int y = dx2[i];
		if (y == fa)
			continue;
		get_col(y,y,0);
	}

	get_number(x,x,0,0);
	for (int i=first2[x]; i; i = nxt2[i]) {
		int y = dx2[i];
		if (y == fa)
			continue;
		handle(y,x);
	}
}

inline void work(int x,int fa) {
	vector<node> l;
	l.clear();
	for (multiset<node>::iterator it = v[x].begin(); it != v[x].end(); it++)
		l.push_back((*it));
	int len = l.size();
	
	
	vector<int> tmp;
	tmp.clear();
	for (int q = 1; q <= m; q++) {
		int last = len - 1;
		int p = req[q];
		if (ans[q])
			continue;
		for (int i = 0; i < len && (!ans[q]); i++) {
			if (i > 0 && l[i].x != l[i - 1].x) {
				for (int j = 0; j < tmp.size(); j++)
					b[tmp[j]]--;
				tmp.clear();
			} else {
				if (tmp.size() - b[l[i].id] > 0) {
					ans[q] = 1;
					break;
				}
			}
			while (l[last].x + l[i].x > p && last > 0)
				last--;
			if (last == 0 && l[last].x + l[i].x > p)
				break;
			while (l[last].x + l[i].x == p) {
				b[l[last].id]++;
				tmp.push_back(l[last].id);
				if (last > 0)
					last--;
				if (last == 0)
					break;
			}
			if (tmp.size() - b[l[i].id] > 0)
				ans[q] = 1;
		}
		for (int i=0; i<tmp.size(); i++)
			b[tmp[i]]--;
		tmp.clear();
	}
	
	for (int i = first2[x]; i; i = nxt2[i]) {
		int y = dx2[i];
		if (y == fa)
			continue;
		work(y,x);
	}

}

int main() {
//	freopen("poj2114.in","r",stdin);
//	freopen("poj2114.out","w",stdout);
	int o = 0;
	while (1 == 1) {
		n = read();
	
		if (n == 0)
			break;
		for (int i=1; i <= n; i++) {
			x = read();
			while (x) {
				y = read();
				build1(i,x,y);
				build1(x,i,y);
				x = read();
			}
		}
		dfs(1,0);
		for (int i=0; i<=n; i++)
			used[i] = 0;
		
		col[rt] = rt;
		handle(rt,0);
	
		int tmp = read();
		while (tmp) {
			req[++m] = tmp;		
			tmp = read();
		}
		
		work(rt,0);
		
		for (int i=1; i<=m; i++) {
			if (ans[i] || req[i] == 0) {
				puts("AYE");
				ans[i] = 0;
			} else
				puts("NAY");
		}
		puts(".");
	
		init();
		
	}
	
	return 0;
}

回复

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

正在加载回复...