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;
}
看了幾個小時了,真沒看出慢在哪了。。。