蒟蒻再次求助

P4168 [Violet] 蒲公英

arfa @ 2018-09-29 13:42:20

Uses math;

var
    node_num,block_num,tail,now,k,n,m,i,j,l,r,tmp1,tmp2:longint;
    num,sortn,place:array[-1..110000] of longint;
    times:array[-1..350,-1..110000] of longint;
    ans:array[-1..350,-1..350] of longint;
    bucket,recf:array[-1..110000] of longint;
    real:array[1..2] of longint;

procedure swap(var a,b:longint); var t:longint; begin t:=a; a:=b; b:=t; end;

function Locate(node:longint):longint;
begin
    if node mod node_num=0 then exit(node div node_num);
    exit(node div node_num+1);
end;

procedure Sort(l,r:longint);
var i,j,s,t:longint;
begin
    i:=l; j:=r; s:=sortn[(l+r) div 2];
    repeat
        while sortn[i]<s do inc(i);
        while sortn[j]>s do dec(j);
        if i<=j then
        begin swap(sortn[i],sortn[j]); swap(place[i],place[j]); inc(i); dec(j); end;
    until i>=j;
    if i<r then Sort(i,r);
    if j>l then Sort(l,j);
end;

procedure Ready;
begin
    read(n,m); node_num:=trunc(sqrt(n)); block_num:=node_num;
    if block_num<>sqrt(n) then inc(block_num);
    for i:=1 to n do begin read(num[i]); place[i]:=i; sortn[i]:=num[i]; end;
    Sort(1,n); tail:=0; sortn[0]:=-666;
    for i:=1 to n do 
    begin
        if sortn[i-1]<>sortn[i] then begin inc(tail); recf[tail]:=sortn[i]; end;
        num[place[i]]:=tail;
    end;

    j:=1;
    for i:=1 to n do
    begin
        inc(times[j,num[i]]);
        if i mod (block_num-1)=0 then
        begin
            for k:=1 to tail do times[j+1,k]:=times[j,k];
            inc(j);
        end;
    end;
    for i:=1 to block_num do
        for j:=i to block_num do
        begin
            now:=ans[i,j-1]; 
            for k:=(j-1)*node_num+1 to min(n,j*node_num) do
            begin
                inc(bucket[num[k]]);
                tmp1:=bucket[num[k]]+times[j-1,num[k]]-times[i-1,num[k]];
                tmp2:=bucket[now]+times[j-1,now]-times[i-1,now];
                if (tmp1>tmp2)or((tmp1=tmp2)and(num[k]<now)) then now:=num[k];
            end;
            for k:=(j-1)*node_num+1 to min(n,j*node_num) do bucket[num[k]]:=0;
            ans[i,j]:=now;
        end;
end;

begin
    Ready; now:=0;
    for i:=1 to m do
    begin
        read(l,r);
        l:=(l+recf[now]+1) mod n+1;
        r:=(r+recf[now]+1) mod n+1;
        if l>r then swap(l,r);
        real[1]:=Locate(l); real[2]:=Locate(r);
        if real[2]-real[1]<=1 then
        begin
            now:=0; bucket[0]:=0;
            for k:=l to r do
            begin
                inc(bucket[num[k]]);
                if (bucket[num[k]]>bucket[now])or((bucket[num[k]]=bucket[now])and(now>num[k])) then now:=num[k];
            end;
            for k:=l to r do bucket[num[k]]:=0;
            writeln(recf[now]);
        end
        else
        begin
            now:=ans[real[1]+1,real[2]-1];
            for k:=l to min(n,real[1]*node_num) do
            begin
                inc(bucket[num[k]]);
                tmp1:=bucket[num[k]]+times[real[2]-1,num[k]]-times[real[1],num[k]];
                tmp2:=bucket[now]+times[real[2]-1,now]-times[real[1],now];
                if (tmp1>tmp2)or((tmp1=tmp2)and(now>num[k])) then now:=num[k];
            end;
            for k:=(real[2]-1)*node_num+1 to r do
            begin
                inc(bucket[num[k]]);
                tmp1:=bucket[num[k]]+times[real[2]-1,num[k]]-times[real[1],num[k]];
                tmp2:=bucket[now]+times[real[2]-1,now]-times[real[1],now];
                if (tmp1>tmp2)or((tmp1=tmp2)and(now>num[k])) then now:=num[k];
            end;
            for k:=l to min(n,real[1]*node_num) do bucket[num[k]]:=0;
            for k:=(real[2]-1)*node_num+1 to r do bucket[num[k]]:=0;
            writeln(recf[now]);
        end;
    end;
end.

by Juan_feng @ 2018-09-29 13:46:23

p大佬%%%


by x_angelkawaii_x @ 2018-09-29 13:55:38

@arfa
pascal啊,溜了溜了


by cecilia_sankta @ 2018-09-29 14:19:56

pascal呀,我不会(光速逃


by ___new2zy___ @ 2018-09-29 14:37:05

p党啊

反正ORZ就对了(雾)


|