莫队bzoj1878

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1878

分析:

莫队模板题
将询问分成sqrt(n)块,每一块按r分别排序。
从(l,r)得到(l,r+1)或(l,r-1)或(l+1,r)或(l-1,r)
①(l,r)到(l,r+1):判断新加入的颜色原来是否存在,若不存在就将种类加1
②(l,r)到(l,r-1):判断去掉的颜色在(l,r-1)中是否还存在,若不存在就将种类减1
③(l,r)到(l-1,r):判断新加入的颜色原来是否存在,若不存在就将种类加1
④(l,r)到(l+1,r):判断去掉的颜色在(l+1,r)中是否还存在,若不存在就将种类减1


代码:

type
  node=record
    l,r,id,pos:longint;
  end;
var
  c,cnt,ans:array [1..1000001] of int64;
  a:array [1..200001] of node;
  i,j:longint;
  m,n,l,r,k,block:int64;


procedure pai1(l,r:longint);
var
  i,j,mid1,mid2:longint;
  t:node;
begin
  i:=l;
  j:=r;
  mid1:=a[(l+r) div 2].pos;
  mid2:=a[(l+r) div 2].r;
  repeat
    while (a[i].pos     while (a[j].pos>mid1) or ((a[j].pos=mid1) and (a[j].r>mid2)) do dec(j);
    if i<=j then
    begin
      t:=a[i];
      a[i]:=a[j];
      a[j]:=t;
      inc(i);
      dec(j);
    end;
  until i>j;
  if l   if i end;


begin
  assign(input,'necklace.in');
  assign(output,'necklace.out');
  reset(input);
  rewrite(output);


  readln(n);
  for i:=1 to n do
  read(c[i]);
  readln;
  block:=trunc(sqrt(n));
  readln(m);
  for i:=1 to m do
  begin
    a[i].id:=i;
    readln(a[i].l,a[i].r);
    a[i].pos:=(a[i].l-1) div block+1;
  end;
  pai1(1,m);
  l:=1;
  r:=0;
  for i:=1 to m do
  begin
    if a[i].l=a[i].r then
    begin
      ans[a[i].id]:=1;
      continue;
    end;
    while r     begin
      inc(r);
      if cnt[c[r]]=0 then
      inc(k);
      inc(cnt[c[r]]);
    end;
    while r>a[i].r do
    begin
      dec(cnt[c[r]]);
      if cnt[c[r]]=0 then
      dec(k);
      dec(r);
    end;
    while l     begin
      dec(cnt[c[l]]);
      if cnt[c[l]]=0 then
      dec(k);
      inc(l);
    end;
    while l>a[i].l do
    begin
      dec(l);
      if cnt[c[l]]=0 then
      inc(k);
      inc(cnt[c[l]]);
    end;
    ans[a[i].id]:=k;
  end;
  for i:=1 to m do
  writeln(ans[i]);


  close(input);
  close(output);
end.



数据:http://download.csdn.net/detail/boyxiejunboy/9423259

你可能感兴趣的:(bzoj)