这题是树上合并,但是我没学过树上合并,只是知道合并时大集合吞并小集合时间复杂度就是nlogn
所以写了一个很很很的代码
这里用unordered_map来表示集合
但是我直接用unordered_map之间的赋值就会超时,代码只能得到70pts 提交链接
https://www.luogu.com.cn/record/154149323
所以我改成了使用对unoudered_map的引用来写 代码如下:
但是一直在for(auto i:mp)这里报错,不知道是什么问题
请问这里是为什么报错,对map使用引用和实值有这么大的区别。
#include<unordered_map>
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<utility>
#include<string>
#include<queue>
#include<cmath>
#include<stack>
#include<array>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pa;
const ll N = 1ll << 19, MOD = 998244353, INF = 0x7fffffffffffff;
const ll M = 1e9 + 7, MM = 1e9 + 9, B = 233;
class cmp {
public:
bool operator() (const pa& x, const pa& y)const {
if (x.second != y.second)return x.second > y.second;
else return x.first < y.first;
}
};
ll t, n, m, k;
vector<ll> c(n + 1);
vector<vector<ll>> nxt;
ll ans;
pair<unordered_map<ll,ll>&,array<ll,3>&> dfs(ll ind) {
unordered_map<ll, ll> ma;
ma[c[ind]]++;
ll is = 1, num = 1, cnt = 0;
for (ll np : nxt[ind]) {
auto tmp = dfs(np);
unordered_map<ll, ll> mp = tmp.first;
array<ll, 3> info = tmp.second;
if (mp.size() > ma.size()) {
mp.swap(ma);
swap(is, info[0]);
swap(num, info[1]);
swap(cnt, info[2]);
}
for (auto i : mp) {
ll res;
bool e = ma.count(i.second);
if (e) res = ma[i.first] + i.second;
else res = i.second;
if (res > num) cnt = ma.size() - e, num = res;
else if (res < num) cnt += !e;
else cnt -= e;
ma[i.first] += i.second;
}
}
// 暴力统计是否是颜色平衡树
/*
bool is = 1;
ll num = ma[c[ind]];
for (auto i : ma)if (i.second != num)is = 0;
if (is)ans++;
return ma;
*/
// 思考如何优化
// 子树是不是颜色平衡 bool
// 子树的最大颜色数 ll
// 子树颜色小于最大颜色数的颜色数 ll
array<ll, 3> re;
if (cnt == 0)is = 1;
re[0] = is;
re[1] = num;
re[2] = cnt;
//for (auto i : ma)cout << i.first << ":" << i.second << " ";
//cout << '\n';
//cout << "info:" << is << " " << num << " " << cnt << '\n';
if (cnt == 0)ans++;
return { ma,re };
}
void solve() {
cin >> n;
c.resize(n + 1);
nxt.resize(n + 1);
ll f;
for (int i = 1; i <= n; i++) {
cin >> c[i] >> f;
nxt[f].push_back(i);
}
dfs(1);
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
/*
*/