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[N],s[N][],f[N],cnt[N],data[N],root,total;//son:1left 2right
int fi,num,p,q,le[N],m,n,i,j,ans;
char opt;
struct lbz
{
int a,b;
}x[N];
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][-w]=s[x][w];
if (s[x][w]!=)
f[s[x][w]]=y;
f[x]=f[y];
if (f[y]!=)
if (y==s[f[y]][])
s[f[y]][]=x;
else
s[f[y]][]=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][])
rotate(x,);
else
rotate(x,);
else
if (y==s[f[y]][])
if (x==s[y][])
{
rotate(y,);
rotate(x,);
}
else
{
rotate(x,);
rotate(x,);
}
else
if (x==s[y][])
{
rotate(y,);
rotate(x,);
}
else
{
rotate(x,);
rotate(x,);
}
}
if (f[x]==) root=x;
} int sea(int x,int w)
{
int t;
t=x;
while ()
{
if (data[t]==w) break;
if (w<=data[t])
{
if (s[t][]==) break;
t=s[t][];
}
else
{
if (s[t][]==) break;
t=s[t][];
} }
splay(t,);
return t;
}
void add(int w)
{
int x;
if (total==)
{
total++;
f[]=;cnt[]=;data[]=w;root=;
return;
}
x=root;
while()
{
cnt[x]++;
if (w<=data[x])
{
if (s[x][]==) break;
x=s[x][];
}
else
{
if (s[x][]==) break;
x=s[x][];
}
}
total++;
data[total]=w;
f[total]=x;
cnt[total]=;
if (w<=data[x])
s[x][]=total;
else
s[x][]=total;
splay(total,);
} void pushdown(int x)
{
lazy[x]^=;
lazy[s[x][]]^=;
lazy[s[x][]]^=;
swap(s[x][],s[x][]);
}
int find(int k,int w)//w=1 Kthsmall;w=2 Kthbig
{
int i,t;
i=root;t=k;
if (lazy[i]==)
pushdown(i); while (t!=cnt[s[i][w]]+)
{ if (t>cnt[s[i][w]]+)
{
t-=cnt[s[i][w]]+;
i=s[i][-w];
}
else
i=s[i][w];
if (lazy[i]==)
pushdown(i);
}
splay(i,);
return i;
} int rec(int l,int r)
{
int ll,rr;
ll=find(l,);
rr=find(r+,);
splay(ll,);
splay(rr,ll);
lazy[s[rr][]]^=;
}
int main()
{
scanf("%d",&n);
for (i=;i<=n;i++)
{
scanf("%d",&x[i].a);
x[i].b=i;
}
sort(x+,x++n,cmp);
for (i=;i<=n;i++)
add(x[i].b);
add();
add(-);
while ()
{
fi=find(,);
if (fi==) break;
rec(,fi);
ans++;
}
printf("%d\n",ans);
return ;
}

最新文章

  1. geotrellis使用(二十一)自动导入数据
  2. 可在广域网部署运行的QQ高仿版 -- GG叽叽V1.8(源码)
  3. 54B
  4. Javascript高性能动画与页面渲染
  5. Bug 是改不完滴
  6. java下的第一个redis
  7. (Problem 37)Truncatable primes
  8. 小说接入UC浏览器内核技术对话(二)
  9. 数据挖掘进阶之关联规则挖掘FP-Growth算法
  10. form组件+cookie+session总结
  11. cookie 和 session 的异同
  12. 【TYVJ 1056】能量项链
  13. paramiko
  14. java34
  15. [No0000130]WPF 4.5使用标记扩展订阅事件
  16. python5-10 检查用户名
  17. JS控制函数执行次数(可带参数)
  18. JavaScript高级编程——Array数组迭代(every()、filter()、foreach()、map()、some(),归并(reduce() 和reduceRight() ))
  19. 牛客网 Java 工程师能力评估 20 题 - 详解
  20. 团队项目个人进展——Day07

热门文章

  1. css - inline-block 盒子下的内容文字错位问题
  2. leetcode第32题:最长有效括号
  3. mysql表关联问题(第二卷:外键1对多之2)
  4. &lt;USACO09JAN&gt;气象测量/气象牛The Baric Bovineの思路
  5. xstream的介绍及用法
  6. iOS自动化登录测试demo
  7. Linux用户与用户组的关系
  8. JavaScript中的innerHTML属性的使用
  9. NOI Online 赛前刷题计划
  10. 【Mood】八上期末考