zoukankan      html  css  js  c++  java
  • 分块算法

    算法就是将n个数序列分成块k块,每次操作时可以一次操作一块,不需要暴力挨个操作,这是分块的主要思想。

    修改时,可以给每个块设置一个加法标记(就是记录这个块中元素加了多少),每次操作对每个整块直接标记,而不完整的块由于元素比较少,可以暴力修改元素的值。

    查询时,何求该差不多,在块上的元素直接乘上,不完整的块暴力。

    修改:

     1 void modify(int a,int b,int c)
     2 {
     3     
     4     for(int i=a;i<=min(bl[a]*blo,b);i++)
     5     {
     6         v[i]+=c;
     7         sum[bl[a]]+=c;
     8     }
     9     if(bl[a] != bl[b])
    10         for(int i=(bl[b]-1)*blo+1;i<=b;i++)
    11         {
    12             v[i] += c;
    13             sum[bl[b]] += c;            
    14         }
    15     for(int i=bl[a]+1;i<=bl[b]-1;i++)
    16         atag[i] += c;
    17 }

    查询区间的和:

     1 int query(int a,int b)
     2 {
     3     int ans=0;
     4     for(int i=a;i<=min(bl[a]*blo,b);i++)
     5         ans += v[i]+add[bl[a]];
     6     if(bl[a] != bl[b])
     7         for(int i=(bl[b]-1)*blo+1;i<=b;i++)
     8             ans += v[i]+atag[bl[b]];
     9     for(int i=bl[a]+1;i<=bl[b]-1;i++)
    10         ans += sum[i]+blo*add[i];
    11     return ans;
    12 }

    合起来就这样了(模板)

     1 /*-------------------------分块*/ 
     2 const int N = 10010;
     3 int n,blo;  //block块 
     4 int bl[N];  //
     5 int v[N],add[N],sum[N];  //v数字,add增加值,sum和 
     6 
     7 void modify(int a,int b,int c)
     8 {
     9     
    10     for(int i=a;i<=min(bl[a]*blo,b);i++)
    11     {
    12         v[i]+=c;
    13         sum[bl[a]]+=c;
    14     }
    15     if(bl[a] != bl[b])
    16         for(int i=(bl[b]-1)*blo+1;i<=b;i++)
    17         {
    18             v[i] += c;
    19             sum[bl[b]] += c;            
    20         }
    21     for(int i=bl[a]+1;i<=bl[b]-1;i++)
    22         atag[i] += c;
    23 }
    24 
    25 int query(int a,int b)
    26 {
    27     int ans=0;
    28     for(int i=a;i<=min(bl[a]*blo,b);i++)
    29         ans += v[i]+add[bl[a]];
    30     if(bl[a] != bl[b])
    31         for(int i=(bl[b]-1)*blo+1;i<=b;i++)
    32             ans += v[i]+atag[bl[b]];
    33     for(int i=bl[a]+1;i<=bl[b]-1;i++)
    34         ans += sum[i]+blo*add[i];
    35     return ans;
    36 }
    37 
    38 int main()
    39 {
    40     /*------------预处理---*/
    41     scanf("%d",&n);
    42     blo = sqrt(n);
    43     for(int i=1; i<=n; i++)
    44         scanf("%d",&v[i]);
    45     for(int i=1; i<=n; i++)
    46     {
    47         bl[i] = (i-1)/blo+1;    //i点属于bl[i]块 
    48         sum[bl[i]] += v[i];        //每一块的总和 
    49     }
    50     //...
    51     return 0;
    52 }
  • 相关阅读:
    Codeforces 812E Sagheer and Apple Tree ——(阶梯博弈)
    2017年浙江省赛总结
    UVALive 3716 DNA Regions ——(扫描法)
    UVALive 3716 DNA Regions ——(式子变形)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    Egyptian Collegiate Programming Contest (ECPC 2015) C题 Connecting Graph
    UVALive 4726 Average ——(斜率优化DP)
    CodeForces 494B Obsessive String ——(字符串DP+KMP)
    [BUUOJ记录] [极客大挑战 2019]RCE ME
    [BUUOJ记录] [GXYCTF2019]BabySQli
  • 原文地址:https://www.cnblogs.com/mjtcn/p/6836444.html
Copyright © 2011-2022 走看看