您的位置:首页 > 其它

codevs1743

2016-09-13 21:15 190 查看
http://codevs.cn/problem/1743/

splay区间翻转。

数字在原序列中的位置保存在splay的data[]中。splay中点的编号为原序列的数字大小。

每次pushdown只在find时进行就行,因为find结束时splay只会改动i点祖先的信息,而其余时候没有splay操作了。

记得加个+INF 一个-INF。

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 400000
#define INF 2000000000
int lazy
,s
[3],f
,cnt
,data
,root,total;//son:1left 2right
int fi,num,p,q,le
,m,n,i,j,ans;
char opt;
struct lbz
{
int a,b;
}x
;
bool cmp(lbz a,lbz b)
{
return a.a<b.a;
}
void rotate(int x,int w)//w:1leftZag 2rightZig
{
int y;
y=f[x];
cnt[y]=cnt[y]-cnt[x]+cnt[s[x][w]];
cnt[x]=cnt[x]-cnt[s[x][w]]+cnt[y];
s[y][3-w]=s[x][w];
if (s[x][w]!=0)
f[s[x][w]]=y;
f[x]=f[y];
if (f[y]!=0)
if (y==s[f[y]][1])
s[f[y]][1]=x;
else
s[f[y]][2]=x;
f[y]=x;
s[x][w]=y;
}
void splay(int x,int t)
{
int y;
while (f[x]!=t)
{
y=f[x];
if (f[y]==t)
if (x==s[y][1])
rotate(x,2);
else
rotate(x,1);
else
if (y==s[f[y]][1])
if (x==s[y][1])
{
rotate(y,2);
rotate(x,2);
}
else
{
rotate(x,1);
rotate(x,2);
}
else
if (x==s[y][2])
{
rotate(y,1);
rotate(x,1);
}
else
{
rotate(x,2);
rotate(x,1);
}
}
if (f[x]==0) root=x;
}

int sea(int x,int w)
{
int t;
t=x;
while (1)
{
if (data[t]==w) break;
if (w<=data[t])
{
if (s[t][1]==0) break;
t=s[t][1];
}
else
{
if (s[t][2]==0) break;
t=s[t][2];
}

}
splay(t,0);
return t;
}
void add(int w)
{
int x;
if (total==0)
{
total++;
f[1]=0;cnt[1]=1;data[1]=w;root=1;
return;
}
x=root;
while(1)
{
cnt[x]++;
if (w<=data[x])
{
if (s[x][1]==0)    break;
x=s[x][1];
}
else
{
if (s[x][2]==0)    break;
x=s[x][2];
}
}
total++;
data[total]=w;
f[total]=x;
cnt[total]=1;
if (w<=data[x])
s[x][1]=total;
else
s[x][2]=total;
splay(total,0);
}

void pushdown(int x)
{
lazy[x]^=1;
lazy[s[x][1]]^=1;
lazy[s[x][2]]^=1;
swap(s[x][1],s[x][2]);
}
int find(int k,int w)//w=1 Kthsmall;w=2 Kthbig
{
int i,t;
i=root;t=k;
if (lazy[i]==1)
pushdown(i);

while (t!=cnt[s[i][w]]+1)
{

if (t>cnt[s[i][w]]+1)
{
t-=cnt[s[i][w]]+1;
i=s[i][3-w];
}
else
i=s[i][w];
if (lazy[i]==1)
pushdown(i);
}
splay(i,0);
return i;
}

int rec(int l,int r)
{
int ll,rr;
ll=find(l,1);
rr=find(r+2,1);
splay(ll,0);
splay(rr,ll);
lazy[s[rr][1]]^=1;
}
int main()
{
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d",&x[i].a);
x[i].b=i;
}
sort(x+1,x+1+n,cmp);
for (i=1;i<=n;i++)
add(x[i].b);
add(1000000000);
add(-1000000000);
while (1)
{
fi=find(2,1);
if (fi==1) break;
rec(1,fi);
ans++;
}
printf("%d\n",ans);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: