zoukankan      html  css  js  c++  java
  • BZOJ2741:[FOTILE模拟赛]L

    Description

    FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和。
    即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r。
    为了体现在线操作,对于一个询问(x,y):
    l=min(((x+lastans)mod N)+1,((y+lastans)mod N)+1).
    r=max(((x+lastans)mod N)+1,((y+lastans)mod N)+1).
    其中lastans是上次询问的答案,一开始为0。

    Input

    第一行两个整数N和M。
    第二行有N个正整数,其中第i个数为Ai,有多余空格。
    后M行每行两个数x,y表示一对询问。

    Output

    共M行,第i行一个正整数表示第i个询问的结果。

    Sample Input

    3 3
    1 4 3
    0 1
    0 1
    4 3

    Sample Output

    5
    7
    7

    HINT

    N=12000,M=6000,x,y,Ai在signed longint范围内。

    题解:

    把元素数组aa替换为前缀异或和数组qz,则询问变成了指定区间内最大的两个元素异或和。

    假如某个元素x已经确定,那么我们只要在区间中找到一个数y,使x xor y最大。

    这可以用字典树在O(log)的复杂度内实现。因为是指定的一个区间,所以要采用可持久化字典树。

    为了减少复杂度,采取分块的做法。

    将n分为√n块,对于每块的第一个元素i,用a[i,j]表示i到j的区间中的最大连续异或和。

    转移方式:a[i,j]:=max(a[i,j-1],qz[j]在[i,j-1]的字典树中的最大异或和)。

    注意不要忘了以[i,j]异或和作为答案的情况(即qz[i-1]xor qz[j])。

    预处理好a数组后,开始处理询问[l,r]。

    找到第一个比l大的分块首元素i(i=k*√n+1),分情况讨论。

    若r≥i,则答案为max(a[i,r],qz[l≤j≤i-1]在[j+1,r]的字典树中的最大异或和);

    若r<i,则答案为max(qz[l≤j≤r]在[l,j-1]的字典树中的最大异或和),注意考虑以[l,j]异或和作为答案的情况(即qz[l-1]xor qz[j])。

    代码:

     1 uses math;
     2 var
     3   t:array[0..600000,0..1,0..1]of longint;
     4   a:array[0..120,0..12001]of longint;
     5   qz,aa:array[0..12001]of longint;
     6   r:array[0..12001]of longint;
     7   b:array[0..34]of longint;
     8   i,ii,j,k,n,m,block,mm,cnt,x,y,ans:longint;
     9   l,ll,rr:int64;
    10 procedure cl(y,yy,z:longint);
    11 var i:longint;
    12 begin
    13   if z=-1 then exit;
    14   i:=x and(1 shl z);
    15   if i>0 then
    16   begin
    17     inc(cnt); t[yy,0]:=t[y,0];
    18     t[yy,1,1]:=cnt; t[yy,1,0]:=t[y,1,0]+1;
    19     cl(t[y,1,1],t[yy,1,1],z-1); exit;
    20   end;
    21   inc(cnt); t[yy,1]:=t[y,1];
    22   t[yy,i,1]:=cnt; t[yy,i,0]:=t[y,i,0]+1;
    23   cl(t[y,i,1],t[yy,i,1],z-1);
    24 end;
    25 function qq(y,yy,z:longint):longint;
    26 var i:longint;
    27 begin
    28   if z=-1 then exit(0);
    29   i:=x and(1 shl z);
    30   if i>0 then
    31   begin
    32     if t[yy,0,0]-t[y,0,0]>0 then
    33     exit(b[z]+qq(t[y,0,1],t[yy,0,1],z-1));
    34     exit(qq(t[y,1,1],t[yy,1,1],z-1));
    35   end;
    36   if t[yy,1,0]-t[y,1,0]>0 then
    37   exit(b[z]+qq(t[y,1,1],t[yy,1,1],z-1));
    38   exit(qq(t[y,0,1],t[yy,0,1],z-1));
    39 end;
    40 begin
    41   b[0]:=1;
    42   for i:=1 to 30 do b[i]:=b[i-1]*2;
    43   readln(n,m);
    44   for i:=1 to n do
    45   begin
    46     read(aa[i]); qz[i]:=aa[i] xor qz[i-1]; x:=qz[i];
    47     inc(cnt); r[i]:=cnt; cl(r[i-1],cnt,30);
    48   end;
    49   block:=trunc(sqrt(n)*1.5)+1;
    50   block:=min(n,block);
    51   i:=1;
    52   while i<=n do
    53   begin
    54     inc(mm);
    55     a[mm,i]:=aa[i];
    56     for j:=i+1 to n do
    57     begin
    58       x:=qz[j]; a[mm,j]:=max(a[mm,j-1],x xor qz[i-1]);
    59       a[mm,j]:=max(a[mm,j],qq(r[i-1],r[j-1],30));
    60     end;
    61     i:=i+block;
    62   end;
    63   for i:=1 to m do
    64   begin
    65     readln(ll,rr);
    66     l:=max((ll+ans)mod n+1,(rr+ans)mod n+1);
    67     ll:=min((ll+ans)mod n+1,(rr+ans)mod n+1);
    68     k:=l; j:=ll; l:=0;
    69     while block*l+1<=j do inc(l);
    70     if block*l+1<=k then
    71     begin
    72       ans:=a[l+1,k]; l:=block*l;
    73       for ii:=j to l do
    74       begin
    75         x:=qz[ii-1];
    76         ans:=max(ans,qq(r[ii-1],r[k],30));
    77       end;
    78     end else
    79     begin
    80       ans:=aa[j];
    81       for ii:=j+1 to k do
    82       begin
    83         x:=qz[ii]; ans:=max(ans,x xor qz[j-1]);
    84         ans:=max(ans,qq(r[j-1],r[ii-1],30));
    85       end;
    86     end;
    87     writeln(ans);
    88   end;
    89 end.
    View Code
  • 相关阅读:
    Codeforces 845E Fire in the City 线段树
    Codeforces 542D Superhero's Job dp (看题解)
    Codeforces 797F Mice and Holes dp
    Codeforces 408D Parcels dp (看题解)
    Codeforces 464D World of Darkraft
    Codeforces 215E Periodical Numbers 容斥原理
    Codeforces 285E Positions in Permutations dp + 容斥原理
    Codeforces 875E Delivery Club dp
    Codeforces 888F Connecting Vertices 区间dp (看题解)
    Codeforces 946F Fibonacci String Subsequences dp (看题解)
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6273214.html
Copyright © 2011-2022 走看看