分块大法好!
考虑分块,首先对每块内进行排序;
对于修改,对于整块的修改,显然只要打一个标记就可以了;
不是整块就暴力修改,然后对那个块重新排序;
这样查询的时候就可以做到在整块内二分,非整块暴力查找即可
显然块取sqrt(n)合适,时间复杂度为O(nsqrt(n)*logn)

  1 var a,b,c,be:array[0..1000010] of longint;
  2     i,m,n,x,y,z,size,q:longint;
  3     ch:char;
  4 
  5 function min(a,b:longint):longint;
  6   begin
  7     if a>b then exit(b) else exit(a);
  8   end;
  9 
 10 procedure sort(l,r: longint);
 11   var i,j,x,y: longint;
 12   begin
 13     i:=l;
 14     j:=r;
 15     x:=b[(l+r) div 2];
 16     repeat
 17       while b[i]<x do inc(i);
 18       while x<b[j] do dec(j);
 19       if not(i>j) then
 20       begin
 21         y:=b[i];b[i]:=b[j];b[j]:=y;
 22         inc(i);
 23         j:=j-1;
 24       end;
 25     until i>j;
 26     if l<j then sort(l,j);
 27     if i<r then sort(i,r);
 28   end;
 29 
 30 
 31 function getans(x,z:longint):longint;
 32   var l,r,m,p:longint;
 33   begin
 34     l:=(x-1)*size+1;
 35     r:=min(l+size-1,n);
 36     p:=r;
 37     while l<=r do
 38     begin
 39       m:=(l+r) shr 1;
 40       if (b[m]<z) then l:=m+1 else r:=m-1;
 41     end;
 42     exit(p-l+1);
 43   end;
 44 
 45 procedure work(x:longint);
 46   var l,r,i:longint;
 47   begin
 48     l:=(x-1)*size+1;
 49     r:=min(l+size-1,n);
 50     for i:=l to r do
 51       b[i]:=a[i];
 52     sort(l,r);
 53   end;
 54 
 55 function ask(x,y,z:longint):longint;
 56   var i:longint;
 57   begin
 58     if be[y]=be[x] then
 59     begin
 60       ask:=0;
 61       for i:=x to y do
 62         if a[i]+c[be[x]]>=z then ask:=ask+1;
 63     end
 64     else begin
 65       ask:=0;
 66       for i:=be[x]+1 to be[y]-1 do
 67         ask:=ask+getans(i,z-c[i]);
 68       for i:=x to be[x]*size do
 69         if a[i]>=z then inc(ask);
 70       for i:=(be[y]-1)*size+1 to y do
 71         if a[i]>=z then inc(ask);
 72     end;
 73   end;
 74 
 75 procedure change(x,y,z:longint);
 76   var i:longint;
 77   begin
 78     if be[y]=be[x] then
 79     begin
 80       for i:=x to y do
 81         a[i]:=a[i]+z;
 82       work(be[x]);
 83     end
 84     else begin
 85       for i:=be[x]+1 to be[y]-1 do
 86         c[i]:=c[i]+z;
 87       for i:=x to be[x]*size do
 88         a[i]:=a[i]+z;
 89       work(be[x]);
 90       for i:=(be[y]-1)*size+1 to y do
 91         a[i]:=a[i]+z;
 92       work(be[y]);
 93     end;
 94   end;
 95 
 96 begin
 97   readln(n,q);
 98   size:=trunc(sqrt(n));
 99   for i:=1 to n do
100   begin
101     read(a[i]);
102     be[i]:=(i-1) div size+1;
103   end;
104   readln;
105   m:=n div size;
106   if n mod size>0 then inc(m);
107   for i:=1 to m do
108     work(i);
109   for i:=1 to q do
110   begin
111     readln(ch,x,y,z);
112     if ch='A' then writeln(ask(x,y,z))
113     else change(x,y,z);
114   end;
115 end.
View Code

 

posted on 2014-12-25 19:47  acphile  阅读(115)  评论(0编辑  收藏  举报