社区讨论
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 条回复,欢迎继续交流。
正在加载回复...