【libreOJ模板】并查集(输入挂,取模与find优化)

1.了解了各种输入挂性orz,找到了一个合适的

2.find用while写能快一倍,并且能被数据卡掉

3.取模只能快十几毫秒,但也能被数据卡掉

取模find双优化是1997mm过的

再加一个性价比较高的输入挂是438mm  23333

#include <cstdio>
#include <cmath>
#include <complex>
#include <algorithm>
#include <iostream>
#include<string.h>
#include<vector>
#include<ctime>
#define rep(i,t,n)  for(int i =(t);i<=(n);++i)
#define per(i,n,t)  for(int i =(n);i>=(t);--i)
#define mmm(a,b) memset(a,b,sizeof(a))
typedef long long ll;
using namespace std;
#define N 2333333
const ll M= 998244353;
const int maxn = 4e6 + 5;
int f[maxn];
using namespace std;

template<typename T>inline void add_(T &A, int B, ll MOD = M) { A += B; (A >= MOD) && (A -= MOD); }
template<typename T>inline void mul_(T &A, ll B, ll MOD = M) { A = (A*B) % MOD; }
namespace IO
{
    const int MAXL = 1 << 15;
    char buf[MAXL], *S, *T, ch;

    inline char Getch()
    {
        if (S == T) T = (S = buf) + fread(buf, 1, MAXL, stdin);
        return S == T ? EOF : *S++;
    }

    inline void Read(int &x)
    {
        x = 0;
        while (!isdigit(ch = Getch()));
        do { x = x * 10 + (ch ^ ‘0‘); } while (isdigit(ch = Getch()));
    }
}
using namespace IO;

int  find(int x) {
    while (f[x] ^ x)x = f[x] = f[f[x]]; return x;
}
void un(int x, int y) {
    int xx = find(x), yy = find(y);
    if(xx^yy)f[xx] = yy;
}
int main() {
    int n, m;
    cin >> n >> m;
    rep(i, 1, n)f[i] = i;
    int op, a,  b;
    ll ans = 0;
    rep(i, 1, m) {
        Read(op); Read(a); Read(b);
        if(!op)un(a, b);
        else {
            add_(ans, ans + (find(a) == find(b)));
        }
    }
    cout << ans << endl;
    cin >> n;
}

原文地址:https://www.cnblogs.com/SuuT/p/9648299.html

时间: 2024-10-04 18:31:56

【libreOJ模板】并查集(输入挂,取模与find优化)的相关文章

LibreOJ #109. 并查集

二次联通门 : LibreOJ #109. 并查集 /* LibreOJ #109. 并查集 并查集 */ #include <cstdio> #define Max 4000090 #define Mod 998244353 void read (int &now) { now = 0; register char word = getchar (); while (word < '0' || word > '9') word = getchar (); while (w

算法模板——并查集 2(支持快速即时查询本连通块内容,纯原创!)

实现功能:输入N,现在有N个数:接下来输入任意行,如果是"1 x y"则表示把x和y所在的块合并:如果是"2 x"则表示输出x所在的块的全部内容 原理:其实主要是自己创造了一个可并链line,he表示链头,ta表示链尾,然后对于不同块之间的合并就是直接把两条链对接,也就是一个的尾巴接到另一个的头上,构成新链(由于是链的直接叠加,所以可以做到严格的O(1),并且输出时输出多少复杂度就是多少,完全不存在额外复杂度).然后同时用原本的普通数组并查集进行维护和追踪(理论值为

最小生成树模板+并查集(隐藏)+结构体排序模板

minn[101],g[101][101],u[101]; memset(u,1,sizeof(u)); memset(minn,0x7f,sizeof(minn)); minn[1]=0; u[1]=0; i,j,k,m; total=0; for(i=1;i<=n;i++) { k=0; for(j=1;j<=n;j++) if(u[j]&&(minn[k]>minn[j])) k=j; u[k]=0; for(j=1;j<=n;j++) if(u[j]&

模板 并查集

[模板]并查集 1 int find(int x) 2 { 3 int r = x; 4 while(father[r]!=r) 5 r = father[r]; 6 return r; 7 } 8 /* 9 int find(int x) 10 { 11 if(father[x] == x) 12 return x; 13 else 14 return father[x] =find(father[x]); 15 } 16 */ 17 18 void join(int x,int j) 19

HDU 1213 How Many Tables(模板——并查集)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1213 Problem Description Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the fri

算法模板——并查集

实现功能——操作1:将两个数字合并到一个集合内:操作2:判断两个数字是否在一起 第6行是亮点,这个优化能快出不少,真的 1 var 2 i,j,k,l,m,n:longint; 3 c:array[0..100000] of longint; 4 function getfat(x:longint):longint;inline; 5 begin 6 if c[x]<>x then c[x]:=getfat(c[x]); //亮点在这里么么哒 7 exit(c[x]); 8 end; 9 be

模板——并查集

1 int pa[maxn]; 2 for(int i = 0; i < maxn; i++) pa[i] = i; 3 int findpa(int x) {return pa[x] != x ? findpa(pa[x]) : x;}

poj 1127 Jack Straws 线段相交+并查集

题意: 有n个木棍,给出木棍的两个端点的x,y坐标,判断其中某两个线段是否连通(可通过其他线段连通) #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <map> #include <

今天做题做到了并查集相关的内容~简单介绍一下关于并查集的东西

就例如一个非常简单的题~ 有一堆人 其中某些人是朋友 有如下的规则 如果A和B是朋友 B和C是朋友 那么A和C也是朋友~ 最后我们有n次的查询 每次查询问其中两个人是不是朋友? 这个题我们就可以用到集合的思想~ 例如A和B是朋友 我们可以把A和B放到一个集合里~ C和D是朋友 我们就把C和D放到一个集合里~ 如图 (原谅只会人工画图的笨比) 但如果我们假设A和C也是好朋友 我们就把这两个集合合并起来~ 就是这个样子~我们对所有的“朋友对”进行这样的操作 就会把他们分到一个个集合里 这时候查找他们