首页 > 其他分享 >P8026 [ONTAK2015] Bajtocja 做题笔记

P8026 [ONTAK2015] Bajtocja 做题笔记

时间:2023-06-24 09:11:21浏览次数:48  
标签:weight fa int Bajtocja ONTAK2015 P8026 long fx fy

题目链接

一道好题,本来是做几道启发式合并玩玩,没想到是个哈希。

这一道题需要维护连通性,显然想到使用并查集。

如果两个点在某个图内的父亲相同,显然这两个点就连通了。

但是如果每链接一对点我们就遍历所有点对然后判断父亲,显然爆炸。

于是考虑借鉴一下 CSP 2022 T3 的思路,对于每个点处理一个值 $weight$。

我们再对每张图中的每个点搞一个随机值 $w$,如果 $i$ 的祖先是 $j$,那么给 $weight_i$ 加上 $w_j$ 即可。

这样我们就把每个点的 $weight$ 设成了它在所有的图中祖先节点的权值之和,然后维护有多少对 $weight$ 相等就行了。

这样错误的可能性很小,因为你很难构造出随机的方程,使得 $a_1+a_2+a_3+\cdots +a_d=b_1+b_2+b_3+\cdots b_d$,并且还有一大堆连通性的要求。

但我第一发的模数是 $998244353$,WA 掉一个点,所以模数尽量开大点。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 300005, mod = 998244353;
#define For(i, a, b) for (int i = (a); i <= (b); ++ i)
inline void r (int &x) {
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = getchar ();
    }
    while (ch >= '0' && ch <= '9') {
        s = s * 10 + ch - 48;
        ch = getchar ();
    }
    x = s * w;
}
int d, n, m;
int w[201][5001], fa[201][5001], sz[201][5001];
int weight[5001];
unordered_map <int, int> b;
vector <int> v[201][5001];
int find (int k, int x) {
    if (fa[k][x] != x) {
        fa[k][x] = find (k, fa[k][x]);
        return fa[k][x];
    } else return x;
}
signed main () {
    srand (time (0) );
    r (d); r (n); r (m);
    For (i, 1, d) {
        For (j ,1, n) {
            w[i][j] = (long long) rand () * (long long) rand () % 129319283324;
            weight[j] += w[i][j];
            v[i][j].push_back (j);
            fa[i][j] = j;
            sz[i][j] = 1;
        }
    }
    For (i, 1, n) b[weight[i] ] ++;
    int ans = n;
    For (i, 1, m) {
        int x, y, k;
        r (x); r (y); r (k);
        int fx = find (k, x), fy = find (k, y);
        if (fx == fy) {
            cout << ans << "\n";
            continue;
        }
        if (sz[k][fx] > sz[k][fy]) swap (fx, fy);
        fa[k][fx] = fy;
        sz[k][fy] += sz[k][fx];
        for (int i : v[k][fx]) {
            ans -= (-- b[weight[i] ]) * 2;
            weight[i] -= w[k][fx];
            weight[i] += w[k][fy];
            ans += b[weight[i] ] * 2;
            b[weight[i] ] ++;
            v[k][fy].push_back (i);
        }
        v[k][fx].clear ();
        cout << ans << "\n";
    }
    return 0;
}

 

标签:weight,fa,int,Bajtocja,ONTAK2015,P8026,long,fx,fy
From: https://www.cnblogs.com/Xy-top/p/17500670.html

相关文章

  • P8026 『JROI-7』hibernal 做题笔记
    题目链接观察数据,要求询问次数不超过$\lceil2\logn\rceil-1$,相当困难。我刚开始也在想二分,但这个东西并不具有单调性,但这个题具有的特点就是你不仅仅可以询问一个前缀,你还可以询问任意的集合。首先发现如果能将$n$个苹果分成$S_1$$S_2$两个长度接近的集合,且$S_1$和$S......