题意:给定n个点,多次询问某个矩阵中包含多少点
如果暴力二维树状数组的话O(nlogn*logn+mlogn*logn)复杂度原地爆炸
那么我们就把二维树状数组通过一些方法变成一维,就能降下去一个log
离线处理
把所有的询问按照二维树状数组的套路拆成四个,
分别把给定点的坐标和拆开后的询问按横坐标排序
对于当前询问,把x小于等于这个询问横坐标的点都加入树状数组,在树状数组中询问小于等于当前询问的纵坐标的点的个数
bzoj 1935 不用离散化..
type
rec2=record
x,y,op,pos:longint;
end;
type
rec1=record
x,y:longint;
end;
var
a :array[0..500010] of rec1;
q :array[0..2000010] of rec2;
i,j :longint;
t :array[0..10000010] of longint;
ans :array[0..500010] of longint;
n,m,tot :longint;
x1,x2,y1,y2 :longint;
procedure add(x,v:longint);
begin
while (x<=10000001) do
begin
inc(t[x],v);
inc(x,x and (-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,x and (-x));
end;
exit(ans);
end;
procedure sort1(l,r:longint);
var
i,j,xx,yy:longint;
z:rec1;
begin
i:=l; j:=r; xx:=a[(l+r)>>1].x; yy:=a[(l+r)>>1].y;
while i<=j do
begin
while (a[i].xxx) or ((a[j].x=xx) and (a[j].y>yy)) do dec(j);
if i<=j then
begin
z:=a[i]; a[i]:=a[j]; a[j]:=z;
inc(i); dec(j);
end;
end;
if il then sort1(l,j);
end;
procedure sort2(l,r:longint);
var
i,j,xx,yy:longint;
z:rec2;
begin
i:=l; j:=r; xx:=q[(l+r)>>1].x; yy:=q[(l+r)>>1].y;
while i<=j do
begin
while (q[i].xxx) or ((q[j].x=xx) and (q[j].y>yy)) do dec(j);
if i<=j then
begin
z:=q[i]; q[i]:=q[j]; q[j]:=z;
inc(i); dec(j);
end;
end;
if il then sort2(l,j);
end;
begin
read(n,m);
for i:=1 to n do
begin
read(a[i].x,a[i].y);
inc(a[i].x); inc(a[i].y);
end;
sort1(1,n);
//
for i:=1 to m do
begin
read(x1,y1,x2,y2);
inc(X1); inc(x2); inc(y1); inc(y2);
inc(tot); q[tot].x:=x1-1; q[tot].y:=y1-1; q[tot].op:=1; q[tot].pos:=i;
inc(tot); q[tot].x:=x2; q[tot].y:=y2; q[tot].op:=1; q[tot].pos:=i;
inc(tot); q[tot].x:=x1-1; q[tot].y:=y2; q[tot].op:=-1; q[tot].pos:=i;
inc(tot); q[tot].x:=x2; q[tot].y:=y1-1; q[tot].op:=-1; q[tot].pos:=i;
end;
sort2(1,tot);
//
j:=1;
for i:=1 to tot do
begin
while (j<=n) and (a[j].x<=q[i].x) do
begin
add(a[j].y,1); inc(j);
end;
inc(ans[q[i].pos],q[i].op*find(q[i].y));
end;
for i:=1 to m do writeln(ans[i]);
end.
type
rec1=record
x,y,p,pos:longint;
end;
type
rec2=record
num,pos:longint;
end;
type
rec3=record
x1,y1,x2,y2:longint;
end;
var
n,m,tot :longint;
i,j :longint;
t :array[0..600010] of int64;
q :array[0..400010] of rec1;
a :array[0..100010] of rec1;
c :array[0..100010] of rec3;
b :array[0..600010] of rec2;
ans :array[0..100010] of int64;
procedure add(x,v:longint);
begin
while x<=tot do
begin
inc(t[x],int64(v));
inc(x,x and (-x));
end;
end;
function find(x:longint):int64;
var
ans:int64;
begin
ans:=0;
while x>0 do
begin
inc(ans,t[x]);
dec(x,x and (-x));
end;
exit(ans);
end;
procedure sort1(l,r:longint);
var
i,j,x:longint;
y:rec2;
begin
i:=l; j:=r; x:=b[(l+r)>>1].num;
while i<=j do
begin
while b[i].numx do dec(j);
if i<=j then
begin
y:=b[i]; b[i]:=b[j]; b[j]:=y;
inc(i); dec(j);
end;
end;
if il then sort1(l,j);
end;
procedure sort2(l,r:longint);
var
i,j,x,y:longint;
z:rec1;
begin
i:=l; j:=r; x:=a[(l+r)>>1].x; y:=a[(l+r)>>1].y;
while i<=j do
begin
while (a[i].xx) or ((a[j].x=x) and (a[j].y>y)) do dec(j);
if i<=j then
begin
z:=a[i]; a[i]:=a[j]; a[j]:=z;
inc(i); dec(j);
end;
end;
if il then sort2(l,j);
end;
procedure sort3(l,r:longint);
var
i,j,x,y:longint;
z:rec1;
begin
i:=l; j:=r; x:=q[(l+r)>>1].x; y:=q[(l+r)>>1].y;
while i<=j do
begin
while (q[i].xx) or ((q[j].x=x) and (q[j].y>y)) do dec(j);
if i<=j then
begin
z:=q[i]; q[i]:=q[j]; q[j]:=z;
inc(i); dec(j);
end;
end;
if il then sort3(l,j);
end;
procedure lsh;
var
i,tt:longint;
begin
for i:=1 to n do
begin
b[i].num:=a[i].x; b[i].pos:=i;
b[i+n].num:=a[i].y; b[i+n].pos:=n+i;
end;
for i:=1 to m do
begin
b[(n<<1)+i].num:=c[i].x1; b[(n<<1)+i].pos:=(n<<1)+i;
b[(n<<1)+m+i].num:=c[i].y1; b[(n<<1)+m+i].pos:=(n<<1)+m+i;
b[(n<<1)+m+m+i].num:=c[i].x2; b[(n<<1)+m+m+i].pos:=(n<<1)+m+m+i;
b[(n<<1)+m+m+m+i].num:=c[i].y2; b[(n<<1)+m+m+m+i].pos:=(n<<1)+m+m+m+i;
end;
tt:=(n<<1)+(m<<2);
sort1(1,tt);
//
tot:=1;
if b[1].pos<=n then a[b[1].pos].x:=tot else
if b[1].pos<=(n<<1) then a[b[1].pos-n].y:=tot else
if b[1].pos<=(n<<1)+m then c[b[1].pos-(n<<1)].x1:=tot else
if b[1].pos<=(n<<1)+(m<<1) then c[b[1].pos-(n<<1)-m].y1:=tot else
if b[1].pos<=(n<<1)+m*3 then c[b[1].pos-(n<<1)-(m<<1)].x2:=tot else c[b[1].pos-(n<<1)-3*m].y2:=tot;
for i:=2 to tt do
begin
if b[i].num<>b[i-1].num then inc(tot);
if b[i].pos<=n then a[b[i].pos].x:=tot else
if b[i].pos<=(n<<1) then a[b[i].pos-n].y:=tot else
if b[i].pos<=(n<<1)+m then c[b[i].pos-(n<<1)].x1:=tot else
if b[i].pos<=(n<<1)+(m<<1) then c[b[i].pos-(n<<1)-m].y1:=tot else
if b[i].pos<=(n<<1)+m*3 then c[b[i].pos-(n<<1)-(m<<1)].x2:=tot else c[b[i].pos-(n<<1)-3*m].y2:=tot;
end;
end;
begin
read(n,m);
for i:=1 to n do read(a[i].x,a[i].y,a[i].p);
for i:=1 to m do read(c[i].x1,c[i].y1,c[i].x2,c[i].y2);
lsh;
//
sort2(1,n);
for i:=1 to m do
begin
q[i].x:=c[i].x1-1; q[i].y:=c[i].y1-1; q[i].p:=1; q[i].pos:=i;
q[i+m].x:=c[i].x2; q[i+m].y:=c[i].y2; q[i+m].p:=1; q[i+m].pos:=i;
q[i+(m<<1)].x:=c[i].x1-1; q[i+(m<<1)].y:=c[i].y2; q[i+(m<<1)].p:=-1; q[i+(m<<1)].pos:=i;
q[i+m*3].x:=c[i].x2; q[i+m*3].y:=c[i].y1-1; q[i+m*3].p:=-1; q[i+m*3].pos:=i;
end;
sort3(1,m<<2);
//
j:=1;
for i:=1 to m<<2 do
begin
while (j<=n) and (a[j].x<=q[i].x) do
begin
add(a[j].y,a[j].p); inc(j);
end;
inc(ans[q[i].pos],int64(q[i].p)*find(q[i].y));
end;
for i:=1 to m do writeln(ans[i]);
end.
——by Eirlys