【BZOJ1176】Mokia(CDQ分治)

题意:维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.

修改操作数M<=160000,询问数Q<=10000,W<=2000000.

思路:CDQ分治

每个操作有t,x,y三维偏序关系

对x排序,对t CDQ分治,对y建立树状数组

树状数组可以用一个时间标记避免每次清空

 

  1 type arr=record
  2           x,y,a,b,t,s:longint;
  3          end;
  4 var p,q:array[0..310000]of arr;
  5     t:array[0..200000,1..4]of longint;
  6     ans,a:array[1..210000]of longint;
  7     sum,tim:array[1..2100000]of longint;
  8     n1,n,m,i,x,y,z,x1,y1,x2,y2,time:longint;
  9 
 10 procedure swap(var x,y:arr);
 11 var t:arr;
 12 begin
 13  t:=x; x:=y; y:=t;
 14 end;
 15 
 16 procedure qsort(l,r:longint);
 17 var i,j,mid:longint;
 18 begin
 19  i:=l; j:=r; mid:=q[(l+r)>>1].x;
 20  repeat
 21   while mid>q[i].x do inc(i);
 22   while mid<q[j].x do dec(j);
 23   if i<=j then
 24   begin
 25    swap(q[i],q[j]);
 26    inc(i); dec(j);
 27   end;
 28  until i>j;
 29  if l<j then qsort(l,j);
 30  if i<r then qsort(i,r);
 31 end;
 32 
 33 procedure qsort1(l,r:longint);
 34 var i,j,mid:longint;
 35 begin
 36  i:=l; j:=r; mid:=q[(l+r)>>1].t;
 37  repeat
 38   while mid>q[i].t do inc(i);
 39   while mid<q[j].t do dec(j);
 40   if i<=j then
 41   begin
 42    swap(q[i],q[j]);
 43    inc(i); dec(j);
 44   end;
 45  until i>j;
 46  if l<j then qsort1(l,j);
 47  if i<r then qsort1(i,r);
 48 end;
 49 
 50 function lowbit(x:longint):longint;
 51 begin
 52  exit(x and (-x));
 53 end;
 54 
 55 procedure update(x,y:longint);
 56 begin
 57  while x<=m do
 58  begin
 59   if tim[x]<>time then sum[x]:=0;
 60   tim[x]:=time;
 61   sum[x]:=sum[x]+y;
 62   x:=x+lowbit(x);
 63  end;
 64 end;
 65 
 66 function query(x:longint):longint;
 67 begin
 68  query:=0;
 69  while x>0 do
 70  begin
 71   if tim[x]=time then query:=query+sum[x];
 72   x:=x-lowbit(x);
 73  end;
 74 end;
 75 
 76 
 77 procedure cdq(l,r:longint);
 78 var mid,i,j,l1,r1:longint;
 79 begin
 80  if l=r then exit;
 81  mid:=(l+r)>>1;
 82  l1:=l; r1:=mid+1;
 83  for i:=l to r do
 84   if q[i].t<=mid then
 85   begin
 86    p[l1]:=q[i]; inc(l1);
 87   end
 88    else
 89    begin
 90     p[r1]:=q[i]; inc(r1);
 91    end;
 92  for i:=l to r do q[i]:=p[i];
 93  cdq(l,mid);
 94  j:=l; inc(time);
 95  for i:=mid+1 to r do
 96  begin
 97   while (j<=mid)and(q[j].x<=q[i].x) do
 98   begin
 99    if q[j].b=0 then update(q[j].y,q[j].a);
100    inc(j);
101   end;
102   if q[i].b=1 then q[i].s:=q[i].s+query(q[i].y);
103  end;
104  cdq(mid+1,r);
105  l1:=l; r1:=mid+1;
106  for i:=l to r do
107   if ((q[l1].x<q[r1].x)and(l1<=mid))or(r1>r) then
108   begin
109    p[i]:=q[l1]; inc(l1);
110   end
111    else
112    begin
113     p[i]:=q[r1]; inc(r1);
114    end;
115  for i:=l to r do q[i]:=p[i];
116 
117 end;
118 
119 begin
120  assign(input,'bzoj1176.in'); reset(input);
121  assign(output,'bzoj1176.out'); rewrite(output);
122  read(n1); read(m); inc(m);
123  while not eof do
124  begin
125   read(x);
126   if x=3 then break;
127   inc(n1);
128   case x of
129    1:
130    begin
131     inc(n);
132     read(q[n].x,q[n].y,q[n].a);
133     inc(q[n].x); inc(q[n].y);
134     q[n].b:=0;
135     q[n].t:=n;
136    end;
137    2:
138    begin
139     read(x1,y1,x2,y2);
140     inc(n); q[n].x:=x1; q[n].y:=y1; q[n].b:=1; q[n].t:=n; t[n1,1]:=n;
141     inc(n); q[n].x:=x1; q[n].y:=y2+1; q[n].b:=1; q[n].t:=n; t[n1,2]:=n;
142     inc(n); q[n].x:=x2+1; q[n].y:=y1; q[n].b:=1; q[n].t:=n; t[n1,3]:=n;
143     inc(n); q[n].x:=x2+1; q[n].y:=y2+1; q[n].b:=1; q[n].t:=n; t[n1,4]:=n;
144    end;
145   end;
146  end;
147  qsort(1,n);
148  cdq(1,n);
149  qsort1(1,n);
150  for i:=1 to n1 do ans[i]:=q[t[i,1]].s+q[t[i,4]].s-q[t[i,2]].s-q[t[i,3]].s;
151  for i:=1 to n1 do
152   if t[i,1]>0 then writeln(ans[i]);
153  close(input);
154  close(output);
155 end.

 

posted on 2017-02-27 17:11  myx12345  阅读(199)  评论(0编辑  收藏  举报

导航