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;
}

看了几个小时了,真没看出慢在哪了。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值