bzoj 1878 树状数组+离线

题意:m组询问,求[l,r]中包含了多少种不同的权值

离线+树状数组,还是原来的配方,还是熟悉的呆马...

把询问按l从小到大排序,

i指针从1到n扫,保证每种权值在[i,r]中第一次出现的位置在树状数组中赋为1,其余位置为0

当i与当前询问的l重合时,当前询问的答案为[l,r]的区间和

type
        rec=record
            l,r,num:longint;
end;

var
        n,m,tot,ll      :longint;
        i,j             :longint;
        ans             :array[0..200010] of longint;
        a               :array[0..200010] of rec;
        first,last      :array[0..1000010] of longint;
        t               :array[0..100010] of longint;
        c,next          :array[0..50010] of longint;
function lowbit(x:longint):longint;
begin
   exit(x and (-x));
end;

procedure sort1(ll,rr:longint);
var
        i,j:longint;
        x:longint;
        y:rec;
begin
   i:=ll;j:=rr;
   x:=a[(ll+rr) div 2].l;
   while (i<=j) do
   begin
      while (a[i].lx) do dec(j);
      if (i<=j) then
      begin
         y:=a[i];a[i]:=a[j];a[j]:=y;
         inc(i);dec(j);
      end;
   end;
   if (ill) then sort1(ll,j);
end;

procedure add(x:longint);
begin
   while (x<=n) do
   begin
      inc(t[x]);
      inc(x,lowbit(x));
   end;
end;

function find(x:longint):longint;
var
        ans:longint;
begin
   ans:=0;
   while (x>0) do
   begin
      inc(ans,t[x]);
      dec(x,lowbit(x));
   end;
   exit(ans);
end;

begin
   read(n);
   for i:=1 to n do
   begin
      read(c[i]);
      if (c[i]>tot) then tot:=c[i];
   end;
   //
   read(m);
   for i:=1 to m do read(a[i].l,a[i].r);
   for i:=1 to m do a[i].num:=i;
   sort1(1,m);
   for i:=1 to n do
   begin
      if (last[c[i]]=0) then
      begin
         last[c[i]]:=i;
         first[c[i]]:=i;
      end else
      begin
         next[last[c[i]]]:=i;
         last[c[i]]:=i;
      end;
   end;

   //
   for i:=1 to tot do
     if (first[i]<>0) then add(first[i]);
   //
   ll:=1;
   for i:=1 to m do
   begin
      for j:=ll to a[i].l-1 do
        if next[j]<>0 then add(next[j]);
      ans[a[i].num]:=find(a[i].r)-find(a[i].l-1);
      ll:=a[i].l;
   end;
   //
   for i:=1 to m do writeln(ans[i]);
end.
——by Eirlys

你可能感兴趣的:(树状数组,bzoj,离线处理)