数据结构

数据结构

链表

单链表

双链表

手写模拟

单调栈

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int stk[maxn], tp;
int n;
int main() {
    cin >> n;
    int tp = 0;
    while(n--) 
    {
        int x; cin>>x;
        while (tp && stk[tp] >= x) tp--;
        if(tp) cout<<stk[tp]<<' ';
        else cout<<-1<<' ';
        stk[++tp] = x;
    }
}

队列

手写模拟

单调队列

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e6+5;

int n, k;

int g[maxn];

int q[maxn]; int hd, rr;   // hd头 rr 尾

int main() {
    scanf("%d%d", &n, &k);
    for(int i=1; i<=n; i++) scanf("%d", &g[i]);

    hd = 0, rr = -1;

    for(int i=1; i<=n; i++) {
        if (hd <= rr && i - k >= q[hd]) hd++;  //判断出窗口

        while(hd <= rr && g[q[rr]] >= g[i]) rr--;

        q[++rr] = i;

        if(i >= k) printf("%d ", g[q[hd]]);
    }

    puts("");

    hd = 0,  rr = -1;

    for(int i=1; i<=n; i++) {
        if (hd <= rr && i - k >= q[hd]) hd++;  //判断出窗口

        while(hd <= rr && g[q[rr]] <= g[i]) rr--;

        q[++rr] = i;

        if(i >= k) printf("%d ", g[q[hd]]);
    }
}

KMP

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5+5, M = 1e6+5;

char p[N], s[M];

int n, m;

int ne[N];

int main() {
    cin>>n>>p+1>>m>>s+1;

    ne[1] = 0;

    for(int i=2, j=0; i<=n ; i++) {
        while(j && p[i] != p[j+1]) j = ne[j];
        if(p[i] == p[j+1]) j++;

        ne[i] = j;
    }

    for(int i=1, j=0; i<=m; i++) {
        while(j && s[i] != p[j+1]) j = ne[j];

        if(s[i] == p[j+1]) j++;

        if(j == n) {
            cout<<i - n<<' ';    
        }
    }
}

Trie

维护一个字符串集合,支持两种操作:
“I x”向集合中插入一个字符串x;
“Q x”询问一个字符串在集合中出现了多少次。

#include <bits/stdc++.h>
using namespace std;

const int maxl = 1e5+5;

int trie[maxl][26], cct[maxl], idx;

int n;

char str[maxl];

int insert (char str[]) {
    int p = 0;
    for(int i=0; str[i]; i++) {
        int c = str[i] - 'a';
        if(!trie[p][c]) trie[p][c] = idx++;
        p = trie[p][c];
    }

    cct[p] ++;
}

int query (char str[]) {
    int p = 0;
    for(int i=0; str[i]; i++) {
        int c = str[i] - 'a';
        if(!trie[p][c]) return 0;
        p = trie[p][c];
    }

    return cct[p];
}

int main (){
    cin>>n; idx = 1;
    while(n--) {
        string CMD;
        cin>>CMD>>str;
        if(CMD == "I") insert(str);
        else cout<<query(str)<<endl;
    }

}

并查集

朴素并查集

带路径压缩的并查集

int find(int x) {
    if(g[x] != x) g[x] = find(g[x]);

    return g[x];
}

维护一些特殊属性的并查集

食物链

int find(int x) {
    if (p[x] != x) {
        int u = find(p[x]); //找到父亲
        d[x] += d[p[x]]; //此时父亲的距离已经被更新
        p[x] = u;
    }
    return p[x];
}

手写堆

#include <iostream>
using namespace std;

const int maxn = 1e5+5;

int heap[maxn], hp[maxn], ph[maxn], idx, sz, n;

void heap_swap(int a, int b)
{
    swap(ph[hp[a]], ph[hp[b]]);
    swap(hp[a], hp[b]);
    swap(heap[a], heap[b]);
}

void down(int t)
{
    int u = t;
    if(2 * t <= sz && heap[2*t] < heap[u]) u = 2 * t;
    if(2 * t + 1 <= sz && heap[2*t+1] < heap[u]) u = 2 * t + 1;
    if(u != t) {
        heap_swap(u, t);
        down(u);
    }
}

void up(int t)
{
    while(t/2 && heap[t/2] > heap[t]) heap_swap(t/2, t), t /= 2;
}

int main() {
    cin >> n;
    while(n--) {
        string p; cin>>p;
        if(p == "I") {
            int x; cin >> x;
            heap[++sz] = x;
            hp[sz] = ++idx;
            ph[idx] = sz;
            up(sz);
        }

        if(p == "PM") {
            cout << heap[1] <<endl;
        }

        if(p == "DM") {
            heap_swap(1, sz);
            sz--;
            down(1);
        }

        if(p == "D") {
            int k; cin >> k;
            k = ph[k];
            heap_swap(sz, k);
            sz--;

            down(k), up(k);
        }

        if(p == "C") {
            int k, x; cin>>k>>x;
            heap[ph[k]] = x;
            down(ph[k]);
            up(ph[k]);
        }
    }
}

堆排序

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5+5;

int n, m, sz;

int g[maxn];

void down(int u) {
    int t = u;
    if(2 * u <= sz && g[2 * u] < g[t]) t = 2 * u;
    if(2 * u + 1 <= sz && g[2 * u + 1] < g[t]) t = 2 * u + 1 ;

    if(u != t) {
        swap(g[u], g[t]);
        down(t);
    }
}

int main() {
    cin>> n >> m;

    for(int i=1 ;i<=n; i++) cin>>g[i]; 

    sz = n;

    for(int i=n/2; i; i--) down(i);

    for(int i=1; i<=m; i++) {
        cout<<g[1]<<' ';
        g[1] = g[sz]; sz--;
        down(1);
    }
}

哈希表

模拟散列表

字符串哈希

#include <bits/stdc++.h>
using namespace std;

typedef unsigned long long ULL;

const int md = 131, maxn = 1e5+5;  //131 or 13331

ULL p[maxn], h[maxn]; //h哈希,p存2^

int n, m;

ULL query(int l, int r) {
    return h[r] - h[l-1] * p[r-l+1];//
}

int main() {
    p[0] = 1;
    cin >> n >> m;
    char str[maxn]; cin>>str+1;
    for(int i=1; i<=n; i++) {
        p[i] = p[i-1] * md;
        h[i] = h[i-1] * md + str[i];
    }

    while(m--){
        int l1, r1, l2, r2; cin>>l1>>r1>>l2>>r2;
        if(query(l1, r1) == query(l2, r2)) cout<<"Yes"<<endl;
        else cout << "No"<<endl;
    }
}
posted @ 2021-03-01 15:33  2wx  阅读(49)  评论(0)    收藏  举报