bzoj 1935 && bzoj 4322 离线+树状数组

来源:互联网 发布:windows xp sp3激活码 编辑:程序博客网 时间:2024/06/05 00:21

题意:给定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].x<xx) or ((a[i].x=xx) and (a[i].y<yy)) do inc(i);      while (a[j].x>xx) 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 i<r then sort1(i,r);   if j>l 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].x<xx) or ((q[i].x=xx) and (q[i].y<yy)) do inc(i);      while (q[j].x>xx) 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 i<r then sort2(i,r);   if j>l 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.

bzoj 4322 多写个离散化即可

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].num<x do inc(i);      while b[j].num>x 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 i<r then sort1(i,r);   if j>l 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].x<x) or ((a[i].x=x) and (a[i].y<y)) do inc(i);      while (a[j].x>x) 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 i<r then sort2(i,r);   if j>l 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].x<x) or ((q[i].x=x) and (q[i].y<y)) do inc(i);      while (q[j].x>x) 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 i<r then sort3(i,r);   if j>l 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


0 0
原创粉丝点击