$\rm{NOIp}$板子整理

一、并查集的两种方式

其实就是一个随机化路径压缩,一个启发式合并。

#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <iostream>

#define MAXN 200010

using namespace std ;
int N, M, A, B, C, F[MAXN] ;

namespace _Heuristic{
    int H[MAXN] ;
    int find(int x){
        if (x == F[x]) return x ;
        return F[x] = find(F[x]) ;
    }
    inline void Merge(int x, int y){ // Heuristic Merge 
        int f1 = find(x), f2 = find(y) ; // Insert the less-height tree into the higher tree
        if (H[f1] > H[f2]) F[f2] = f1 ; //because : H[x] < H[y] -> After Insert H[x] to H[y], H[y] ++ or H[y] == ;
        else if (H[f1] < H[f2]) F[f1] = f2 ; //Therefore, we make the tree the lowest height under meaning .
        else F[f1] = f2, ++ H[f2] ;
    }
    void solve2(){
        fill(H, H + N + 2, 1) ;
        while (M --){
            scanf("%d%d%d", &A, &B, &C) ;
            if (A == 2){
                int f1 = find(B), f2 = find(C) ;
                printf("%c\n", f1 == f2 ? 'Y' : 'N') ;
            }
            else Merge(B, C) ; 
        }
    }
}
namespace _Compress{
    int t ;
    int find(int x){
        if (x == F[x]) return x ;
        return F[x] = find(F[x]) ;
    }
    void solve1(){
        srand(time(NULL)) ; 
        while (M --){
            scanf("%d%d%d", &A, &B, &C) ;
            if (A == 2){
                int f1 = find(B), f2 = find(C) ;
                printf("%c\n", f1 == f2 ? 'Y' : 'N') ;
            }
            else {
                int f1 = find(B), f2 = find(C) ;
                if (!(t = rand() % 2)) F[f1] = f2 ; else F[f2] = f1 ;
            }   
        }
    }
}
int main(){
    cin >> N >> M ;  
    for (int i = 1 ; i <= N ; ++ i) F[i] = i  ;
    if (M <= 50000) _Compress::solve1() ; else _Heuristic::solve2() ; return 0 ;
}

二、筛素数的两种方式

其实就是埃氏筛和线性筛啦~

#include <bitset>
#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std ;
int N, M ; 

namespace Es{ // Eratosthenes
    #define MAXN 2000100
    bool vis[MAXN] ; int A, i, j ;
    void Ego(){
        vis[1] = vis[0] = 1 ;
        for (i = 2 ; i <= N ; ++ i){
            if (vis[i])  continue ; 
            for (j = i + i ; j <= N ; j += i) vis[j] = 1 ;
        }
    }
    void solve1(){
        Ego() ;
        while (M --)
            scanf("%d", &A), printf("%s\n", !vis[A] ? "Yes" : "No") ;
    }
    #undef MAXN 
}
namespace Euler{
    #define MAXN 10001000
    bitset <MAXN> vis ;
    int Prime[MAXN], A, i, j, cnt ;
    void Ego(){
        vis[1] = vis[0] = 1 ;
        for (i = 2 ; i <= N ; ++ i){
            if (!vis[i]) Prime[++ cnt] = i ;
            for (j = 1 ; j <= cnt ; ++ j){
                if (i * Prime[j] > N) break ;
                vis[i * Prime[j]] = 1 ;
                if (!(i % Prime[j])) break ;
            }
        }
    }
    void solve2(){
        Ego() ;
        while (M --)
            scanf("%d", &A), printf("%s\n", !vis[A] ? "Yes" : "No") ;
    }
}
int main(){
    cin >> N >> M ;
    if (N <= 1000000) Es::solve1() ; else Euler::solve2() ; return 0 ; 
}

三、最短路的两种方式

\(SPFA + SLF\)+乱搞

#include <deque>
#include <cstdio>
#include <iostream>
 
#define R register 
#define MAXN 200010
#define to(i) E[i].to
#define Inf 2147483647

using namespace std ;
deque <int> q ;
struct Edge{
    int to, next, v ;
}E[MAXN] ; int head[MAXN], cnt ;
int N, M, S, dist[MAXN] ; bool vis[MAXN] ;

inline int qr(){
    int res = 0 ; char c = getchar() ;
    while (!isdigit(c)) c = getchar() ;
    while (isdigit(c)) res = (res << 1) + (res << 3) + c - 48, c = getchar() ;
    return res ; 
}
inline void Add(int u, int v, int w) {
    E[++ cnt].to = v, E[cnt].v = w ;
    E[cnt].next = head[u], head[u] = cnt ;
}
inline void SPFA(){
    for (R int i = 1 ; i <= N ; ++ i) dist[i] = Inf ; 
    dist[S] = 0, q.push_back(S), vis[S] = 1 ;
    while(!q.empty()){
        R int now = q.front() ; 
        q.pop_front(), vis[now] = 0 ;
        for (R int i = head[now] ; i ; i = E[i].next){
            if (dist[to(i)] > dist[now] + E[i].v){
                dist[to(i)] = dist[now] + E[i].v ;
                if (!vis[to(i)]){
                    vis[to(i)] = 1 ;
                    R int F = q.front(), B = q.back() ;
                    if (dist[F] < dist[B]){
                        q.pop_front(), q.pop_back() ;
                        q.push_front(B), q.push_back(F) ;
                        if (dist[B] > dist[to(i)])
                            q.push_front(to(i)) ;
                        else q.push_back(to(i)) ;
                    }
                    else if (dist[F] > dist[to(i)])
                            q.push_front(to(i)) ;
                        else q.push_back(to(i)) ; 
                }
            }
        }
    }
} 
int main(){
    cin >> N >> M >> S ; int A, B, C ;
    for (R int i = 1 ; i <= M ; ++ i) A = qr(), B = qr(), C = qr(), Add(A, B, C) ;
    SPFA() ; for (R int i = 1 ; i <= N ; ++ i) printf("%d ", dist[i]) ; return 0 ;
}

\(Heap + dijkstra\)

#include <deque>
#include <cstdio>
#include <iostream>
 
#define R register 
#define MAXN 200010
#define to(i) E[i].to
#define Inf 2147483647

using namespace std ;
deque <int> q ;
struct Edge{
    int to, next, v ;
}E[MAXN] ; int head[MAXN], cnt ;
int N, M, S, dist[MAXN] ; bool vis[MAXN] ;

inline int qr(){
    int res = 0 ; char c = getchar() ;
    while (!isdigit(c)) c = getchar() ;
    while (isdigit(c)) res = (res << 1) + (res << 3) + c - 48, c = getchar() ;
    return res ; 
}
inline void Add(int u, int v, int w) {
    E[++ cnt].to = v, E[cnt].v = w ;
    E[cnt].next = head[u], head[u] = cnt ;
}
inline void SPFA(){
    for (R int i = 1 ; i <= N ; ++ i) dist[i] = Inf ; 
    dist[S] = 0, q.push_back(S), vis[S] = 1 ;
    while(!q.empty()){
        R int now = q.front() ; 
        q.pop_front(), vis[now] = 0 ;
        for (R int i = head[now] ; i ; i = E[i].next){
            if (dist[to(i)] > dist[now] + E[i].v){
                dist[to(i)] = dist[now] + E[i].v ;
                if (!vis[to(i)]){
                    vis[to(i)] = 1 ;
                    R int F = q.front(), B = q.back() ;
                    if (dist[F] < dist[B]){
                        q.pop_front(), q.pop_back() ;
                        q.push_front(B), q.push_back(F) ;
                        if (dist[B] > dist[to(i)])
                            q.push_front(to(i)) ;
                        else q.push_back(to(i)) ;
                    }
                    else if (dist[F] > dist[to(i)])
                            q.push_front(to(i)) ;
                        else q.push_back(to(i)) ; 
                }
            }
        }
    }
} 
int main(){
    cin >> N >> M >> S ; int A, B, C ;
    for (R int i = 1 ; i <= M ; ++ i) A = qr(), B = qr(), C = qr(), Add(A, B, C) ;
    SPFA() ; for (R int i = 1 ; i <= N ; ++ i) printf("%d ", dist[i]) ; return 0 ;
}

四、矩阵快速幂

主要是成员函数的写法

#include <cstdio>
#include <cstring>
#include <iostream>

#define LL long long
#define Mod 1000000007

using namespace std ;
LL N, K ;
struct Matrix{
    LL M[200][200] ;
    void clear() { memset(M, 0, sizeof(M)) ;}
    void reset() {
        clear() ;
        for (int i = 1 ; i <= N ; ++ i) M[i][i] = 1 ;
    }
    Matrix friend operator *(const Matrix&A, const Matrix &B){
        Matrix Ans ; Ans.clear() ; 
        for (int i = 1 ; i <= N; ++ i)
            for (int j = 1 ; j <= N ; ++ j)
                for (int k = 1 ; k <= N; ++ k)
                    Ans.M[i][j] = (Ans.M[i][j] + A.M[i][k] * B.M[k][j]) % Mod ;
        return Ans ;
    }
    Matrix friend operator +(const Matrix&A, const Matrix &B){
        Matrix Ans ; Ans.clear() ; 
        for (int i = 1 ; i <= N; ++ i)
            for (int j = 1 ; j <= N ; ++ j)
                    Ans.M[i][j] = (A.M[i][j] + B.M[i][j]) % Mod ;
        return Ans ;
    }
} qwq, unit ; 
inline Matrix expow(Matrix T, LL P){
    Matrix Ans ; Ans.reset() ;
    while (P){
        if (P & 1) Ans = Ans * T ;
        T = T * T, P >>= 1 ;
    }
    return Ans ;
}
int main(){
    cin >> N >> K ;
    for (int i = 1 ; i <= N ; ++ i)
        for (int j = 1 ; j <= N ; ++ j)
            cin >> qwq.M[i][j] ;
    qwq = expow(qwq, K) ;
    for (int i = 1 ; i <= N ; ++ i)
        for (int j = 1 ; j <= N ; ++ j)
            printf("%lld%c", qwq.M[i][j], " \n"[j == N]) ;
}

四、二分图匹配

#include <cstdio>
#include <cstring>
#include <iostream>

#define R register 
#define MAXN 2000100
#define to(k) E[k].to

using namespace std  ; 
struct Edge{
    int to, next, v ;
}E[MAXN] ; int head[MAXN], Ans, cnt ;
int N, M, Ew, A, B, used[MAXN] ; bool vis[MAXN] ;

inline void Add(int u, int v) {
    if (u < 1 || v < 1 || u > N || v > M) return ;
    E[++ cnt].to = v, E[cnt].next = head[u], head[u] = cnt ;
}
bool path(int u){
    for (int k = head[u] ; k ; k = E[k].next){
        if (!vis[to(k)]){
            vis [to(k)] = 1 ;
            if (!used[to(k)] || path(used[to(k)])){
                used[to(k)] = u ;
                return 1 ;
            }
        }
    }
    return 0 ;
}
int main(){
    cin >> N >> M >> Ew ;
    while(Ew --) scanf("%d%d", &A, &B), Add(A, B) ;
    for (R int i = 1 ; i <= N ; ++ i)       
        memset(vis, 0, sizeof(vis)), Ans += (int)path(i) ;
    cout << Ans << endl ; return 0 ;
}

剩下的回来再整理吧~~

猜你喜欢

转载自www.cnblogs.com/pks-t/p/9938275.html
rm