暑假学习日记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定理

你可能感兴趣的:(学习)