zoukankan      html  css  js  c++  java
  • [BZOJ3343]教主的魔法|分块

    Description

      教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N。
    每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)
    CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。
    WD巨懒,于是他把这个回答的任务交给了你。
     
      分块算法是指把一个序列分成sqrt(n)块,每块正好有sqrt(n)个元素
      对于这道题,我们先将每个数按顺序分到一个块中,维护每个块内部的单调性
      对于一个M操作,我们把l,r中间的块整块作一个加法的标记,对于两头的直接暴力标
      整块不超过sqrt(n)块,两头的也不超过sqrt(n)个元素,所以时间复杂度还是O(sqrt(n))
      对于A操作,对于暴力的部分很容易统计,对于整块的由于我们之前维护好了单调性,直接二分查找就可以了
      但是这里不要忽略了之前作的add标记
      
      
      1 {
      2     Chunk.
      3 }
      4 
      5 program bzoj3343;
      6 const maxn=1000010;maxm=1010;
      7 var n,q,m,block,x,y,z,i:longint;
      8     ch:char;
      9     a,b,pos:array[-1..maxn]of longint;
     10     add:array[-1..maxm]of longint;
     11 
     12 function min(a,b:longint):longint;
     13 begin
     14     if a<b then exit(a) else exit(b);
     15 end;
     16 
     17 procedure qsort(L,R:longint);
     18 var i,j,mid:longint;
     19 begin
     20     i:=L;j:=R;mid:=b[random(R-L+1)+L];
     21     repeat
     22         while (i<R)and(b[i]>mid) do inc(i);
     23         while (L<j)and(b[j]<mid) do dec(j);
     24         if i<=j then
     25         begin
     26             b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];
     27             inc(i);dec(j);
     28         end;
     29     until i>j;
     30     if i<R then qsort(i,R);
     31     if L<j then qsort(L,j);
     32 end;
     33 
     34 procedure new(p:longint);
     35 var l,r,i:longint;
     36 begin
     37     l:=(p-1)*block+1;r:=min(p*block,n);
     38     for i:=l to r do b[i]:=a[i];
     39     qsort(l,r);
     40 end;
     41 
     42 procedure update(x,y,z:longint);
     43 var i:longint;
     44 begin
     45     if pos[x]=pos[y] then
     46         for i:=x to y do inc(a[i],z) else
     47     begin
     48         for i:=x to pos[x]*block do inc(a[i],z);
     49         for i:=(pos[y]-1)*block+1 to y do inc(a[i],z);
     50     end;
     51     for i:=pos[x]+1 to pos[y]-1 do inc(add[i],z);
     52     new(pos[x]);new(pos[y]);
     53 end;
     54 
     55 function find(x,y:longint):longint;
     56 var L,R,mid:longint;
     57 begin
     58     find:=(x-1)*block;
     59     L:=(x-1)*block+1;R:=x*block;
     60     while L<=R do
     61     begin
     62         mid:=(L+R) >> 1;
     63         if b[mid]>=y then
     64         begin
     65             find:=mid;L:=mid+1;
     66         end else R:=mid-1;
     67     end;
     68     dec(find,(x-1)*block);
     69 end;
     70 
     71 function query(x,y,z:longint):longint;
     72 var tot,i:longint;
     73 begin
     74         tot:=0;
     75     if pos[x]=pos[y] then
     76     begin    for i:=x to y do if a[i]>=z then inc(tot);end else
     77     begin
     78         for i:=x to pos[x]*block do if a[i]>=z then inc(tot);
     79         for i:=(pos[y]-1)*block+1 to y do if a[i]>=z then inc(tot);
     80     end;
     81     for i:=pos[x]+1 to pos[y]-1 do inc(tot,find(i,z-add[i]));
     82         exit(tot);
     83 end;
     84 
     85 begin
     86     readln(n,q);
     87     fillchar(add,sizeof(add),0);
     88     block:=trunc(sqrt(n));
     89     for i:=1 to n do
     90     begin
     91         read(a[i]);
     92         pos[i]:=(i-1) div block+1;//pos[i]表示第i个数所在的块
     93     end;
     94         readln;
     95     if n mod block=0 then m:=n div block else m:=n div block +1;
     96     for i:=1 to m do new(i);
     97         for i:=1 to q do
     98     begin
     99         read(ch);
    100         if ch='M' then
    101         begin
    102             readln(x,y,z);
    103             update(x,y,z);
    104         end else
    105         begin
    106             readln(x,y,z);
    107             writeln(query(x,y,z));
    108         end;
    109     end;
    110 end.
  • 相关阅读:
    Tjoi 2017 异或和
    Noi 十连测 建造记者站
    Noi 十连测 基因改造计划
    Noi 十连测 人生的经验
    NOI 十连测 Round 5 T2 运河计划
    NOI 十连测 Round 5 T1
    【ZJOI2018】迷宫
    BZOJ 十连测 day5 T3
    BZOJ 十连测 可持久化字符串
    BZOJ 十连测 二进制的世界
  • 原文地址:https://www.cnblogs.com/mjy0724/p/4424011.html
Copyright © 2011-2022 走看看