社区讨论

80分,两个点mle,求优化

P3294[SCOI2016] 背单词参与者 1已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@lo3g62ag
此快照首次捕获于
2023/10/24 06:06
2 年前
此快照最后确认于
2023/10/24 06:06
2 年前
查看原帖
没用踹树,方法和题解不太一样。
CPP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <unordered_map>
using namespace std;
typedef long long lld;
unordered_map <string, int> mp; 
const int N = 100005;
const int M = 510005;
int n, pos = -1;
lld ans = 0;
int son[N];
vector <string> s;
vector <int> e[N];
void add(int x, int y) {
	e[x].push_back(y);
}
void dfs(int x) {
	for(int i = 0; i < e[x].size(); i++) {
		int y = e[x][i];
		dfs(y);
		son[x] += son[y];
	}
	son[x]++;
}
struct par {
	int num, sons;
};
par make_p(int a, int b) {
	par e; e.num = a; e.sons = b;
	return e;
}
bool cmp(par a, par b) {
	return a.sons < b.sons;
}
 
void getans(int x) {
	if(son[x] == 1) {
		pos++; ans += pos; return ;
	}
	vector <par> tmp;
	for(int i = 0; i < e[x].size(); i++) {
		int y = e[x][i];
		tmp.push_back(make_p(y, son[y]));
	}
	sort(tmp.begin(), tmp.end(), cmp);
	pos++;
	ans -= pos * (tmp.size() - 1);
	for(int i = 0; i < tmp.size(); i++) {
		getans(tmp[i].num);
	}
}
int main() {
	// freopen("data.in", "r",stdin);
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		char ss[N]; cin >> ss;
		mp[ss] = i; s.push_back(ss);
	}
	for(int i = 0; i < s.size(); i++) {
		int len = s[i].length();
		bool flag = false;
		for(int j = 1; j < len; j++) {
			int fa = mp[s[i].substr(j, len - j)];
			if(fa) {
				e[fa].push_back(i + 1);
				flag = true; break;
			}
		}
		if(!flag) {
			e[0].push_back(i + 1);
		}
	}
	s.clear();
	dfs(0); getans(0);
	printf("%lld\n", ans);
	return 0;
}

回复

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

正在加载回复...