zoukankan      html  css  js  c++  java
  • 暑假学习日记2013/8/5

        前几天去海南旅行没怎么做题,倒是搞了一下多校的那个polya,现在看来如果给我多点时间我应该是能搞出来的,置换群也大概知道怎么找了,以前是没看出那个东西怎么转,现在看出来了,自然就没什么好怕的了~今天在研究Treap,觉得它的名字就是Tree和Heap派生出来的,既有树的形式,也有堆的形式,通过旋转能够平衡,下面贴下代码,代码的模板来源于某道题的标程,自己在后面加了个找第k大值的,下面是模板

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    int N=100000;
    
    const int M = 100000 << 2;
    int root;
    int size[M], number[M], args[M], key[M], indices[M][2];
    int node_count;
    
    void update(int u) {
        size[u] = size[indices[u][0]] + size[indices[u][1]] + number[u];
    }
    
    void rotate(int &u, int d) {
        int v = indices[u][d];
        indices[u][d] = indices[v][d ^ 1];
        indices[v][d ^ 1] = u;
        update(u);
        update(v);
        u = v;
    }
    
    void insert(int &u, int k) {
        if (u == 0) {
            u = ++ node_count;
            size[u] = number[u] = 1;
            key[u] = k;
            args[u] = rand();
            indices[u][0] = indices[u][1] = 0;
        } else if (k == key[u]) {
            number[u] ++;
        } else {
            int d = k > key[u];
            int &v = indices[u][d];
            insert(v, k);
            if (args[v] < args[u]) {
                rotate(u, d);
            }
        }
        update(u);
    }
    
    void erase(int &u, int k) {
        if (u == 0) {
            size[u] = number[u] = indices[u][0] = indices[u][1] = 0;
        } else if (k == key[u]) {
            if (number[u] > 1) {
                number[u] --;
            } else {
                int d = args[indices[u][1]] < args[indices[u][0]];
                rotate(u, d);
                erase(u, k);
            }
        } else {
            int d = k > key[u];
            int &v = indices[u][d];
            erase(v, k);
            if (args[v] < args[u]) {
                rotate(u, d);
            }
        }
        update(u);
    }
    
    bool find(int u, int k) {
        while (u > 0) {
            if (key[u] == k) {
                return true;
            }
            u = indices[u][k > key[u]];
        }
        return false;
    }
    
    int find_greater(int u, int k) {
        int result = 0;
        while (u > 0) {
            if (k <= key[u]) {
                result += size[indices[u][1]] + number[u];
            }
            u = indices[u][k > key[u]];
        }
        return result;
    }
    
    int find_smaller(int u,int k){
        int result=0;
        while(u>0){
            if(k>=key[u]){
                result+=size[indices[u][0]]+number[u];
            }
            u=indices[u][k >= key[u]];
        }
        return result;
    }
    
    int find_equal(int u,int k){
        while (u > 0) {
            if (key[u] == k) {
                return number[u];
            }
            u = indices[u][k > key[u]];
        }
        return 0;
    }
    
    int find_kth(int u,int k){
        if(u==0||k<=0||k>size[u]) return 0;
        int s1=size[indices[u][0]];
        int s2=number[u];
        if(s1<k&&s1+s2>=k){
            return key[u];
        }
        else if(s1+s2<k){
            return find_kth(indices[u][1],k-s1-s2);
        }
        else if(s1>=k){
            return find_kth(indices[u][0],k);
        }
    }
    
    #define clr(x) memset((x), 0, sizeof(x))
    
    void init(){
        clr(size);clr(number);clr(args);clr(key);clr(indices);
        args[0]=INT_MAX;
        node_count=0;
        root=0;
    }
    
    
    int main()
    {
        init();
        int n;cin>>n;
        int otype,okey;
        while(n--)
        {
            scanf("%d%d",&otype,&okey); // 1是插入key值 2是删除key值 3是查找key值 4是询问大于等于key 5询问小于等于 6询问等于 7询问第k大的
            if(otype==1){
                insert(root,okey);
            }
            else if(otype==2){
                erase(root,okey);
            }
            else if(otype==3){
                cout<<find(root,okey)<<endl;
            }
            else if(otype==4){
                cout<<find_greater(root,okey)<<endl;
            }
            else if(otype==5){
                cout<<find_smaller(root,okey)<<endl;
            }
            else if(otype==6){
                cout<<find_equal(root,okey)<<endl;
            }
            else if(otype==7){
                cout<<find_kth(root,okey)<<endl;
            }
        }
        return 0;
    }

    写了个驱动程序测试了下,感觉还行,漏洞还有待发现吧.
    总结一下:

    1.Treap

    2.Polya定理

  • 相关阅读:
    MySQL系列
    Python小白之路
    nrm安装使用(mac)
    npm 发布一个包(已有自己私服的情况)
    vuex简单使用
    在vue中使用ztree树插件
    题库1
    设计模式读书笔记
    ORM框架学习之EF
    net+Oracle开发过程中遇到的小问题
  • 原文地址:https://www.cnblogs.com/chanme/p/3239657.html
Copyright © 2011-2022 走看看