• FUNDAMENTAL PART2 DS


    DS

    +++

    1.单调栈
    #include <iostream>
    
    using namespace std;
    
    const int N = 1e5 + 10;
    
    int stk[N], tt;
    int n;
    
    int main()
    {
        scanf("%d", &n);
        
        int x;
        for (int i = 0; i < n; i ++ )
        {
            scanf("%d", &x);
            while(tt && stk[tt] >= x) tt -- ;
            
            if(tt) printf("%d ", stk[tt]);
            else printf("-1 ");
            
            stk[ ++ tt ] = x;
        }
        
        cout << endl;
        
        return 0;
    }
    
    2.滑动窗口
    #include <iostream>
    
    using namespace std;
    
    const int N = 1e6 + 10;
    
    int a[N], q[N], hh, tt = -1;
    int m, n;
    
    int main()
    {
        scanf("%d%d", &m, &n);
        for (int i = 0; i < m; i ++ ) scanf("%d", a + i);
        
        for (int i = 0; i < m; i ++ )
        {
            if(hh <= tt && i - n + 1 > q[hh]) hh ++ ;
            while(hh <= tt && a[q[tt]] >= a[i]) tt -- ;
            
            q[ ++ tt ] = i;
            if(i >= n - 1) printf("%d ", a[q[hh]]);
        }
        
        puts("");
        
        for (int i = 0; i < m; i ++ )
        {
            if(hh <= tt && i - n + 1 > q[hh]) hh ++ ;
            while(hh <= tt && a[q[tt]] <= a[i]) tt -- ;
            
            q[ ++ tt ] = i;
            if(i >= n - 1) printf("%d ", a[q[hh]]);
        }
        
        puts("");
        
        return 0;
    }
    
    3.KMP
    #include <iostream>
    
    using namespace std;
    
    const int N = 100010, M = 1000010;
    
    int n, m;
    int ne[N];
    char s[M], p[N];
    
    int main()
    {
        cin >> n >> p + 1 >> m >> s + 1;
    
        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)
            {
                printf("%d ", i - n);
                j = ne[j];
            }
        }
    
        return 0;
    }
    
    4.Trie树
    #include <iostream>
    
    using namespace std;
    
    const int N = 2e4 + 10;
    
    int son[N][26], cnt[N], idx;
    char str[N];
    
    void insert(char str[])
    {
        int p = 0;
        for (int i = 0; str[i]; i ++ )
        {
            int u = str[i] - 'a';
            if(!son[p][u]) son[p][u] = ++ idx;
            p = son[p][u];
        }
        
        cnt[p] ++ ;
    }
    
    int query(char str[])
    {
        int p = 0;
        for (int i = 0; str[i]; i ++ )
        {
            int u = str[i] - 'a';
            if(!son[p][u]) return 0;
            p = son[p][u];
        }
        
        return cnt[p];
    }
    
    int main()
    {
        int n;
        scanf("%d", &n);
        
        char op[2];
        while ( n -- )
        {
            scanf("%s%s", op, str);
            if(op[0] == 'I') insert(str);
            else printf("%d
    ", query(str));
        }
        
        return 0;
    }
    
    5.合并集合
    #include <iostream>
    
    using namespace std;
    
    const int N = 1e5 + 10;
    
    int m, n, p[N];
    
    int find(int x)
    {
        if(p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i ++ ) p[i] = i;
        
        while(m -- )
        {
            char op[2];
            int a, b;
            scanf("%s%d%d", op, &a, &b);
            if(op[0] == 'M') p[find(a)] = find(b);
            else
            {
                if(find(a) == find(b)) puts("Yes");
                else puts("No");
            }
        }
        
        return 0;
    }
    
    6.堆排序
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 1e5 + 10;
    
    int h[N], idx;
    int m, n;
    
    
    void down(int u)
    {
        int t = u;
        if(u * 2 <= idx && h[u * 2] < h[t]) t = u * 2;
        if(u * 2 + 1 <= idx && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
        
        if(u != t)
        {
            swap(h[t], h[u]);
            down(t);
        }
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i ++ ) scanf("%d", h + i);
        idx = n;
        
        for (int i = n / 2; i; i -- ) down(i);//O(n)
        
        while (m -- )
        {
            printf("%d ", h[1]);
            h[1] = h[idx -- ];
            down(1);
        }
        puts("");
        
        return 0;
    }
    
    7.模拟散列表
    拉链法
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    const int N = 100003;
    
    int h[N], e[N], ne[N], idx;
    int n;
    
    void insert(int x)
    {
        int k = (x % N + N) % N;
        
        e[idx] = x, ne[idx] = h[k], h[k] = idx ++ ;
    }
    
    bool find(int x)
    {
        int k = (x % N + N) % N;
        
        for (int i = h[k]; i != -1; i = ne[i])
            if(e[i] == x)
                return true;
        
        return false;
    }
    
    int main()
    {
        scanf("%d", &n);
        
        memset(h, -1, sizeof h);
        
        while (n -- )
        {
            int t;
            char op[2];
            scanf("%s%d", op, &t);
            
            if(op[0] == 'I') insert(t);
            else
                if(find(t)) puts("Yes");
                else puts("No");
        }
        
        return 0;
    }
    
    开放寻址法
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    const int N = 200003, null = 0x3f3f3f3f;
    
    int h[N];
    int n;
    
    int find(int x)
    {
        int k = (x % N + N) % N;
        while(h[k] != null && h[k] != x)
        {
            k ++ ;
            if( k == N) k = 0;
        }
        
        return k;
    }
    
    int main()
    {
        scanf("%d", &n);
        
        memset(h, 0x3f, sizeof h);
        
        while (n -- )
        {
            int t;
            char op[2];
            scanf("%s%d", op, &t);
            
            if(*op == 'I') h[find(t)] = t;
            else
                if(h[find(t)] != null) puts("Yes");
                else puts("No");
        }
        
        return 0;
    }
    
    8.字符串哈希
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef unsigned long long ULL;
    
    const int N = 100010, P = 131;
    
    int n, m;
    char str[N];
    ULL h[N], p[N];
    
    int get(int l, int r)
    {
        return h[r] - h[l - 1] * p[r - l + 1];
    }
    
    int main()
    {
        scanf("%d%d%s", &n, &m, str + 1);
        
        p[0] = 1;
        for (int i = 1; i <= n; i ++ )
        {
            p[i] = p[i - 1] * P;
            h[i] = h[i - 1] * P + str[i];
        }
        
        while (m -- )
        {
            int l1, r1, l2, r2;
            scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
            
            if(get(l1, r1) == get(l2, r2)) puts("Yes");
            else puts("No");
        }
        
        return 0;
    }
    
    
    

    STL

    //vector
    vector<int> v(10, 3);//10个vector 每个元素都是3
    vector<int> v[10];
    v.size()//O(1)
    v.empty()//if empty return 1
    v.clear()
    front()/back()
    push_back()/pop_back()
    begin()/end()//迭代器 迭代器的++ -- 复杂度是O(logn)
    vector<int>::iterator i = v.begin()//访问
    //vector支持比较运算,按照字典序比较
    //pair
    pair<int, string> p;
    p = make_pair(10, "abc");
    p = {10, "abc"};
    //string
    string a;
    size() == length()
    a.substr(A, B);//A起始下标,B字串长度。如果省略B,那么直接输出到a串最后一位
    printf("%s", a.c_str());
    //queue
    front()/back()
    push()/pop()
    queue<int> q;
    q = queue<int>();//清空queue
    //priority_queue
    push()/top()/pop()
    priority_queue<int> heap;//默认大根堆
    priority_queue<int, vector<int>, greater<int>> heap;//小根堆
    //set multiset
    //set无重复元素,multiset有重复元素
    insert()//O(logn)
    find()//如果不存在返回end迭代器
    count()//返回某一个值的数量
    erase()//(1)输入一个x,删除所有x  O(k + logn)(2)输入一个迭代器,删除迭代器
    lower_bound(x)//返回大于等于x的最小的数的迭代器
    upper_bound(x)//返回大于x的最小的数的迭代器
    //map multimap
    insert()//插入的是pair
    erase()//输入的参数是pair或者迭代器
    map<string, int> a;
    a["abc"] = 1;//O(logn)
    lower_bound(x)//返回大于等于x的最小的数的迭代器
    upper_bound(x)//返回大于x的最小的数的迭代器
    //unordered_set ...
    //和上面类似,增删改查复杂度O(1)
    //不支持lower_bound(x),upper_bound(x),迭代器++ --
    

    +++

    +++

    1.最大异或对(Trie tree)
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 3100000, M = 1e5 + 10;
    
    int son[N][2], a[M];
    int n, idx;
    
    void insert(int x)
    {
        int p = 0;
        for (int i = 30; i >= 0; i -- )
        {
            int u = x >> i & 1;
            if(!son[p][u]) son[p][u] = ++ idx;
            p = son[p][u];
        }
    }
    
    int query(int x)
    {
        int p = 0, res = 0;
        for (int i = 30; i >= 0; i -- )
        {
            int u = x >> i & 1;
            if(son[p][!u])
            {
                p = son[p][!u];
                res = res * 2 + !u;
            }
            else
            {
                p = son[p][u];
                res = res * 2 + u;
            }
        }
        
        return res;
    }
    
    int main()
    {
        scanf("%d", &n);
        
        for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
        
        int res = 0;
        for (int i = 0; i < n; i ++ )
        {
            insert(a[i]);
            int t = query(a[i]);
            res = max(res, a[i] ^ t);
        }
        
        printf("%d
    ", res);
        
        return 0;
    }
    
  • 相关阅读:
    [LeetCode] 159. Longest Substring with At Most Two Distinct Characters 最多有两个不同字符的最长子串
    [LeetCode] 76. Minimum Window Substring 最小窗口子串
    window.scrollTo和window.scrollBy
    background-clip与background-origin
    page-break-before和page-break-after
    CSS counter计数器(content目录序号自动递增)详解
    移动端网页巧用 margin和padding 的百分比实现自适应
    监听屏幕旋转事件window. onorientationchange
    apple-touch-startup-image 制作iphone web应用程序的启动画面
    当把链接保存到手机桌面。设置图标 只在safari浏览器中有用
  • 原文地址:https://www.cnblogs.com/scl0725/p/13735605.html
Copyright © 2020-2023  润新知