首页 > 其他 > 详细

WIKIOI 3243 区间翻转

时间:2014-08-05 00:12:58      阅读:435      评论:0      收藏:0      [点我收藏+]

给出N个数,要求做M次区间翻转(如1 2 3 4变成4 3 2 1),求出最后的序列

第一行一个数N,下一行N个数表示原始序列,在下一行一个数M表示M次翻转,之后的M行每行两个数L,R表示将区间[L,R]翻转。

一行N个数 , 表示最终序列。

4

1 2 3 4

2

1 2

3 4

2 1 4 3

对于30%的数据满足n<=100 , m <= 10000

对于100%的数据满足n <= 150000 , m <= 150000

对于100%的数据满足n为2的幂,且L = i * 2^j + 1 , R = (i + 1) * 2^j

题解:

要不要这么卡时啊。。。不加inline就不能过?

代码:

bubuko.com,布布扣
  1 {$inline on}
  2 const maxn=150000+100;
  3 var s,id,fa,a:array[0..maxn] of longint;
  4     rev:array[0..maxn] of boolean;
  5     c:array[0..maxn,0..1] of longint;
  6     i,n,m,rt,x,y:longint;
  7     procedure swap(var x,y:longint);inline;
  8      var t:longint;
  9      begin
 10      t:=x;x:=y;y:=t;
 11      end;
 12 
 13 procedure pushup(x:longint);inline;
 14  begin
 15    s[x]:=s[c[x,0]]+s[c[x,1]]+1;
 16  end;
 17 procedure pushdown(x:longint);inline;
 18  var l,r:longint;
 19  begin
 20    l:=c[x,0];r:=c[x,1];
 21    if rev[x] then
 22     begin
 23       swap(c[x,0],c[x,1]);
 24       rev[l]:=not(rev[l]);
 25       rev[r]:=not(rev[r]);
 26       rev[x]:=false;
 27     end;
 28  end;
 29 procedure rotate(x:longint;var k:Longint);inline;
 30  var l,r,y,z:longint;
 31  begin
 32    y:=fa[x];z:=fa[y];
 33    if c[y,0]=x then l:=0 else l:=1;r:=l xor 1;
 34    if y=k then k:=x else c[z,ord(c[z,1]=y)]:=x;
 35    fa[x]:=z;fa[y]:=x;fa[c[x,r]]:=y;
 36    c[y,l]:=c[x,r];c[x,r]:=y;
 37    pushup(y);pushup(x);
 38  end;
 39 procedure splay(x:longint;var k:longint);inline;
 40  var y,z:longint;
 41  begin
 42    while x<>k do
 43     begin
 44       y:=fa[x];z:=fa[y];
 45       if y<>k then
 46         begin
 47           if (c[z,0]=y) xor (c[y,0]=x) then rotate(x,k)
 48           else rotate(y,k);
 49         end;
 50       rotate(x,k);
 51     end;
 52  end;
 53 function find(x,rank:longint):longint;inline;
 54  var l,r:longint;
 55  begin
 56  pushdown(x);l:=c[x,0];r:=c[x,1];
 57  if s[l]+1=rank then exit(x)
 58  else if s[l]>=rank then exit(find(l,rank))
 59  else exit(find(r,rank-s[l]-1));
 60  end;
 61 procedure rever(l,r:longint);inline;
 62  var x,y:longint;
 63  begin
 64  x:=find(rt,l);y:=find(rt,r+2);
 65  splay(x,rt);splay(y,c[x,1]);
 66  rev[c[y,0]]:=not(rev[c[y,0]]);
 67  end;
 68 procedure build(l,r,f:longint);inline;
 69  var mid,now,last:longint;
 70  begin
 71  if l>r then exit;
 72  now:=id[l];last:=id[f];
 73  if l=r then
 74     begin
 75       fa[now]:=last;s[now]:=1;
 76       c[last,ord(l>f)]:=now;
 77       exit;
 78     end;
 79  mid:=(l+r)>>1;
 80  build(l,mid-1,mid);build(mid+1,r,mid);
 81  now:=id[mid];pushup(mid);
 82  fa[now]:=last;
 83  c[last,ord(mid>f)]:=now;
 84  end;
 85 procedure init;
 86  begin
 87    readln(n);
 88    for i:=1 to n do read(a[i]);readln;
 89    readln(m);
 90    for i:=1 to n+2 do id[i]:=i;
 91    build(1,n+2,0);rt:=(n+3)>>1;
 92  end;
 93 procedure main;
 94  begin
 95    for i:=1 to m do
 96     begin
 97       readln(x,y);
 98       rever(x,y);
 99     end;
100    for i:=2 to n+1 do write(a[find(rt,i)-1], );
101  end;
102 begin
103   assign(input,input.txt);assign(output,output.txt);
104   reset(input);rewrite(output);
105   init;
106   main;
107   close(input);close(output);
108 end.
109                                  
View Code

 

WIKIOI 3243 区间翻转,布布扣,bubuko.com

WIKIOI 3243 区间翻转

原文:http://www.cnblogs.com/zyfzyf/p/3891092.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!