Splay的常數問題

Poj 2761

給一個序列,維護區間第K大值,沒有修改。


拿來試Splay的速度,至於我爲什麼現在纔開始測速呢?還是別說的好。。。


總之我發現我的伸展樹的常數奇大無比。。。。。。


希望有大牛可以和我交流一下優化啥的,3610MS。。。手算了一下常數,大概100+吧。。。


都感覺自己玷污Splay這個名字了,


貼一下醜代碼:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 100001;

int f[maxn],s[maxn][2],size[maxn],key[maxn];
int left[maxn],right[maxn],aim[maxn],w[maxn],pos[maxn],answer[maxn];
int n,m,root,node;


void qsort(int l,int r)
{
    int i = l,j = r,x = left[(l+r)/2];
    while (i < j)
    {
        while (left[i] < x) ++i;
        while (left[j] > x) --j;
        if (i <= j)
        {
            swap(left[i],left[j]);
            swap(right[i],right[j]);
            swap(aim[i],aim[j]);
            swap(pos[i],pos[j]);
            ++i; --j;
        }        
    }
    if (l < j) qsort(l,j);
    if (i < r) qsort(i,r);
}

void updata(int x){size[x] = size[s[x][0]]+size[s[x][1]]+1;}

void rotate(int x,int p)
{
    int y = f[x],z = f[y],son = s[x][p^1];
    if (s[z][0] == y) s[z][0] = x;
    if (s[z][1] == y) s[z][1] = x;
    f[x] = z; s[x][p^1] = y;
    f[y] = x; s[y][p] = son;
    f[son] = y;
    updata(y);
}

void splay(int x,int aim)
{
    int y,z,p,q;
    while (f[x] != aim)
    {
        y = f[x],z = f[y];
        if (f[y] != aim)
        {          
            p = s[y][1] == x;
            q = s[z][1] == y;
            if (p == q) rotate(y,q),rotate(x,p);
            else rotate(x,p),rotate(x,q);            
        }
        else rotate(x,s[y][1] == x);
    }
    updata(x);
}

int sa(int x)
{
    int i;
    ++x;
    for (i = root; i; )
    {
        if (x < size[s[i][0]]+1) i = s[i][0];
        else if (x > size[s[i][0]]+1) x -= size[s[i][0]]+1,i = s[i][1];
        else break;        
    }
    return key[i];
}

int pre(int x)
{    
    for (x = s[x][0]; s[x][1]; x = s[x][1]);
    return x;
}

void add(int x)
{
    int i,j;
    for (i = root; i; )
    {
        if (w[x] > key[i]) j = i,i = s[i][1];
        else j = i,i = s[i][0];
    }
    if (w[x] > key[j]) s[j][1] = x;
    else s[j][0] = x;
    f[x] = j;
    key[x] = w[x];
    splay(x,root);
}

void del(int x)
{
    int i,j;
    i = x;
    splay(i,root);
    j = pre(i);
    if (j == 0) f[s[i][1]] = root,s[root][1] = s[i][1];
    else
    {
        splay(j,i);
        f[s[i][1]] = j;
        s[j][1] = s[i][1];
        f[j] = root;
        s[root][1] = j;    
    }
    f[i] = 0;
    s[i][0] = 0; s[i][1] = 0;
}

int main()
{
    int i,j,l,r;  
    freopen("2761.in","r",stdin);
    freopen("2761.out","r",stdout);
    scanf("%d%d",&n,&m);
    for (i = 1; i <= n; ++i) scanf("%d",&w[i]);
    for (i = 1; i <= m; ++i) scanf("%d%d%d",&left[i],&right[i],&aim[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    qsort(1,m);
    l = 1; r = 0; root = n+1;
    for (i = 1; i <= m; ++i)
    {
        if (r < left[i])
        {         
            s[root][1] = 0;
            for (j = left[i]; j <= right[i]; ++j) add(j);
        }
        else
        {
            for (j = l; j < left[i]; ++j) del(j);
            for (j = r+1; j <= right[i]; ++j) add(j);            
        }
        l = left[i]; r = right[i];
        answer[pos[i]] = sa(aim[i]);
    }
    for (i = 1; i <= m; ++i) printf("%d\n",answer[i]);
    return 0;
}

看了幾個小時了,真沒看出慢在哪了。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章