首页 > 代码库 > WIKIOI 3243 区间翻转

WIKIOI 3243 区间翻转

3243 区间翻转 

题目描述 Description

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

输入描述 Input Description

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

输出描述 Output Description

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

样例输入 Sample Input

4

1 2 3 4

2

1 2

3 4

样例输出 Sample Output

2 1 4 3

数据范围及提示 Data Size & Hint

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

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

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

题解:

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

代码:

  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 begin103   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