Luo Gu P2342 stacked bricks solution to a problem

This konjac again made the solution of the problem

This question is a bit like a disjoint-set, but the number is not that asking a little show;

So, ordinary disjoint-set can not solve this problem, this time on the need to use a weighted disjoint-set;

Each run are recorded when a few points below it, and then ask the time complexity is O (1) is;

Well, then you can happily code code:

#include<bits/stdc++.h>
using namespace std; #define maxn 500010 char ch; int n, x, y, fa[maxn], sum[maxn], num[maxn]; //比常规的并查集多了一行 int find(int x) { if(fa[x] == x) return x; sum[x] += sum[fa[x]];//还需要统计它下面的积木数 return fa[x] = find(fa[x]); } //fa[]就不说了,sum[]是来存它下面的积木数,num[]是这一列的积木数; int main() { scanf("%d", &n); for(int i = 1; i <= maxn; ++ i) { fa[i] = i;//嗯,它的祖先就是它自己,常规操作; sum[i] = 0;//它的下面QwQ肯定没有积木啊 num[i] = 1;//目前这一列只有一个积木 } for(int i = 1; i <= n; ++ i) { cin >> ch; if(ch == 'M')//如果这是'M',那就要合并 { scanf("%d%d", &x, &y); x = find(x), y = find(y); if(x != y)//如果他们的祖先不同,就是他们不在同一个联通块上 { fa[x] = y;//合并它们 sum[x] = num[y]; //数量要相加 num[y] += num[x]; //因为x要和y合并 } } else { scanf("%d", &x); find(x);//还需要再来一次; printf("%d\n", sum[x]);//O(1)输出; } } return 0; }

Ah, you took a pleasant 27 points;

Well, start troubleshooting, and

Wearing glasses, eyes wide open

Where is wrong?

It is to make life difficult for data, hey;

Well, I guess so you certainly find where the gods are wrong, I like konjac (crossed out

#include<bits/stdc++.h>
using namespace std; #define maxn 500010 char ch; int n, x, y, fa[maxn], sum[maxn], num[maxn]; //fa[]就不说了,sum[]是来存它下面的积木数,num[]是这一列的积木数; //比常规的并查集多了一行 int find(int x) { if(fa[x] == x) return x; int f = find(fa[x]); sum[x] += sum[fa[x]];//还需要统计它下面的积木数 return fa[x] = f; } int main() { scanf("%d", &n); for(int i = 1; i <= maxn; ++ i) { fa[i] = i;//嗯,它的祖先就是它自己,常规操作; sum[i] = 0;//它的下面QwQ肯定没有积木啊 num[i] = 1;//目前这一列只有一个积木 } for(int i = 1; i <= n; ++ i) { cin >> ch; if(ch == 'M')//如果这是'M',那就要合并 { scanf("%d%d", &x, &y); x = find(x), y = find(y); if(x != y)//如果他们的祖先不同,就是他们不在同一个联通块上 { fa[x] = y;//合并它们 sum[x] = num[y]; //数量要相加 num[y] += num[x]; //因为x要和y合并 } } else { scanf("%d", &x); find(x);//还需要再来一次; printf("%d\n", sum[x]);//O(1)输出; } } return 0; }

Have not found where wrong,

Yes, that is the find function inside;

The first code is:

int find(int x) { if(fa[x] == x) return x; sum[x] += sum[fa[x]];//还需要统计它下面的积木数 return fa[x] = find(fa[x]); }

The second code is:

int find(int x) { if(fa[x] == x) return x; int f = find(fa[x]); sum[x] += sum[fa[x]];//还需要统计它下面的积木数 return fa[x] = f; } 

Is not it, the first is to update the sum [], and then recursively;

It is the first and the second recursive, and then update SUM [];

So, we should be the first recursive finished, again updating;

If the first update, then update the find function and sum [] of no effect;

Ah, it's that the end;

. PS AC code is the second, the first chapter in question;

Guess you like

Origin www.cnblogs.com/Flash-plus/p/11210692.html