zoukankan      html  css  js  c++  java
  • 分块来水题

    luogu P3374 【模板】树状数组 1

    在大牛分站交能过,主站卡常。

    时间复杂度为 n√n ≈ 3.5 * 108,我都不知道怎么过的。。

    ——代码

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 const int MAXN = 500001;
     8 int n, m, S, C;
     9 int a[MAXN], st[MAXN], ed[MAXN], belong[MAXN], sum[MAXN];
    10 
    11 inline void init()
    12 {
    13     int i, j;
    14     scanf("%d %d", &n, &m);
    15     for(i = 1; i <= n; i++) scanf("%d", &a[i]);
    16     S = sqrt(n) + 10;
    17     for(i = 1; i <= n; i += S)
    18     {
    19         st[++C] = i;
    20         ed[C] = min(i + S - 1, n);
    21     }
    22     for(i = 1; i <= C; i++)
    23         for(j = st[i]; j <= ed[i]; j++)
    24             sum[i] += a[j], belong[j] = i;
    25 }
    26 
    27 inline void update(int x, int k)
    28 {
    29     a[x] += k;
    30     sum[belong[x]] += k;
    31 }
    32 
    33 inline int query(int x, int y)
    34 {
    35     int i, ans = 0, l = belong[x], r = belong[y];
    36     if(l == r)
    37     {
    38         for(i = x; i <= y; i++) ans += a[i];
    39         return ans;
    40     }
    41     for(i = x; i <= ed[l]; i++) ans += a[i];
    42     for(i = l + 1; i <= r - 1; i++) ans += sum[i];
    43     for(i = st[r]; i <= y; i++) ans += a[i];
    44     return ans;
    45 }
    46 
    47 inline void work()
    48 {
    49     int i, x, y, z;
    50     for(i = 1; i <= m; i++)
    51     {
    52         scanf("%d %d %d", &z, &x, &y);
    53         if(z == 1) update(x, y);
    54         else printf("%d
    ", query(x, y));
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     init();
    61     work();
    62     return 0;
    63 }
    View Code

    luogu P3368 【模板】树状数组 2

    在大牛分站交能过,主站卡常。

    ——代码

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 const int MAXN = 500001;
     8 int n, m, S, C;
     9 int a[MAXN], belong[MAXN], add[MAXN], st[MAXN], ed[MAXN];
    10 
    11 inline void init()
    12 {
    13     int i, j;
    14     scanf("%d %d", &n, &m);
    15     for(i = 1; i <= n; i++) scanf("%d", &a[i]);
    16     S = sqrt(n);
    17     for(i = 1; i <= n; i += S)
    18     {
    19         st[++C] = i;
    20         ed[C] = min(i + S - 1, n);
    21     }
    22     for(i = 1; i <= C; i++)
    23         for(j = st[i]; j <= ed[i]; j++)
    24             belong[j] = i;
    25 }
    26 
    27 inline void update(int x, int y, int k)
    28 {
    29     int i, l = belong[x], r = belong[y];
    30     if(l == r)
    31     {
    32         for(i = x; i <= y; i++) a[i] += k;
    33         return;
    34     }
    35     for(i = x; i <= ed[l]; i++) a[i] += k;
    36     for(i = l + 1; i <= r - 1; i++) add[i] += k;
    37     for(i = st[r]; i <= y; i++) a[i] += k;
    38 }
    39 
    40 inline void work()
    41 {
    42     int i, x, y, z, d;
    43     for(i = 1; i <= m; i++)
    44     {
    45         scanf("%d %d", &z, &x);
    46         if(z == 1)
    47         {
    48             scanf("%d %d", &y, &d);
    49             update(x, y, d);
    50         }
    51         else printf("%d
    ", a[x] + add[belong[x]]);
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     init();
    58     work();
    59     return 0;
    60 }
    View Code

    luogu P3372 【模板】线段树 1

    这个数据水,主站就能过。

    ——代码

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <iostream>
     4 #define LL long long
     5 
     6 using namespace std;
     7 
     8 const int MAXN = 100001;
     9 int n, m, S, C;
    10 int st[MAXN], ed[MAXN], belong[MAXN];
    11 LL a[MAXN], sum[MAXN], add[MAXN];
    12 
    13 inline void init()
    14 {
    15     int i, j;
    16     scanf("%d %d", &n, &m);
    17     for(i = 1; i <= n; i++) scanf("%lld", &a[i]);
    18     S = sqrt(n);
    19     for(i = 1; i <= n; i += S)
    20     {
    21         st[++C] = i;
    22         ed[C] = min(i + S - 1, n);
    23     }
    24     for(i = 1; i <= C; i++)
    25         for(j = st[i]; j <= ed[i]; j++)
    26             sum[i] += a[j], belong[j] = i;
    27 }
    28 
    29 inline void update(int x, int y, LL k)
    30 {
    31     int i, l = belong[x], r = belong[y];
    32     if(l == r)
    33     {
    34         for(i = x; i <= y; i++) a[i] += k;
    35         sum[l] += (y - x + 1) * k;
    36         return;
    37     }
    38     for(i = x; i <= ed[l]; i++) a[i] += k;
    39     sum[l] += (ed[l] - x + 1) * k;
    40     for(i = l + 1; i <= r - 1; i++)
    41     {
    42         sum[i] += (ed[i] - st[i] + 1) * k;
    43         add[i] += k;
    44     }
    45     for(i = st[r]; i <= y; i++) a[i] += k;
    46     sum[r] += (y - st[r] + 1) * k;
    47 }
    48 
    49 inline LL query(int x, int y)
    50 {
    51     int i, l = belong[x], r = belong[y];
    52     LL ans = 0;
    53     if(l == r)
    54     {
    55         for(i = x; i <= y; i++) ans += a[i] + add[l];
    56         return ans;
    57     }
    58     for(i = x; i <= ed[l]; i++) ans += a[i] + add[l];
    59     for(i = l + 1; i <= r - 1; i++) ans += sum[i];
    60     for(i = st[r]; i <= y; i++) ans += a[i] + add[r];
    61     return ans;
    62 }
    63 
    64 inline void work()
    65 {
    66     int i, x, y, z;
    67     LL k;
    68     for(i = 1; i <= m; i++)
    69     {
    70         scanf("%d %d %d", &z, &x, &y);
    71         if(z == 1)
    72         {
    73             scanf("%lld", &k);
    74             update(x, y, k);
    75         }
    76         else printf("%lld
    ", query(x, y));
    77     }
    78 }
    79 
    80 int main()
    81 {
    82     init();
    83     work();
    84     return 0;
    85 }
    View Code

     

    luogu P3373 【模板】线段树 2

    看了黄学长的讲解,猛然醒悟!%%%%%hzwer

    整块可以直接打标记,而左右两边零散的块要先把它们所属于的整块的标记清除掉再打,否则会错。

    ——代码

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <iostream>
      4 #define LL long long
      5 
      6 using namespace std;
      7 
      8 const int MAXN = 100001;
      9 int n, m, p, S, C;
     10 int st[MAXN], ed[MAXN], belong[MAXN];
     11 LL a[MAXN], sum[MAXN], add[MAXN], mul[MAXN];
     12 
     13 inline void init()
     14 {
     15     int i, j;
     16     scanf("%d %d %d", &n, &m, &p);
     17     for(i = 1; i <= n; i++) scanf("%lld", &a[i]);
     18     S = sqrt(n);
     19     for(i = 1; i <= n; i += S)
     20     {
     21         st[++C] = i;
     22         ed[C] = min(i + S - 1, n);
     23         mul[C] = 1;
     24     }
     25     for(i = 1; i <= C; i++)
     26         for(j = st[i]; j <= ed[i]; j++)
     27             sum[i] += a[j], belong[j] = i;
     28 }
     29 
     30 inline void reset(int x)
     31 {
     32     int i;
     33     for(i = st[x]; i <= ed[x]; i++)
     34         a[i] = (a[i] * mul[x] + add[x]) % p;
     35     sum[x] = (sum[x] * mul[x] + add[x] * (ed[x] - st[x] + 1)) % p;
     36     add[x] = 0, mul[x] = 1;
     37 }
     38 
     39 inline void update(int f, int x, int y, LL k)
     40 {
     41     int i, l = belong[x], r = belong[y];
     42     LL tot;
     43     if(l == r)
     44     {
     45         reset(l);
     46         for(tot = 0, i = x; i <= y; i++)
     47         {
     48             if(f == 1) a[i] = (a[i] * k) % p, tot = (tot + a[i]) % p;
     49             else a[i] = (a[i] + k) % p;
     50         }
     51         if(f == 1) sum[l] = (sum[l] + tot * (k - 1)) % p;
     52         else sum[l] = (sum[l] + (y - x + 1) * k) % p;
     53         return;
     54     }
     55     
     56     reset(l);
     57     for(tot = 0, i = x; i <= ed[l]; i++)
     58     {
     59         if(f == 1) tot = (tot + a[i]) % p, a[i] = (a[i] * k) % p;
     60         else a[i] = (a[i] + k) % p;
     61     }
     62     if(f == 1) sum[l] = (sum[l] + tot * (k - 1)) % p;
     63     else sum[l] = (sum[l] + (ed[l] - x + 1) * k) % p;
     64     
     65     reset(r);
     66     for(tot = 0, i = st[r]; i <= y; i++)
     67     {
     68         if(f == 1) tot = (tot + a[i]) % p, a[i] = (a[i] * k) % p;
     69         else a[i] = (a[i] + k) % p;
     70     }
     71     if(f == 1) sum[r] = (sum[r] + tot * (k - 1)) % p;
     72     else sum[r] = (sum[r] + (y - st[r] + 1) * k) % p;
     73     
     74     for(i = l + 1; i <= r - 1; i++)
     75         if(f == 1)
     76         {
     77             add[i] = (add[i] * k) % p;
     78             mul[i] = (mul[i] * k) % p;
     79         }
     80         else add[i] = (add[i] + k) % p;
     81 }
     82 
     83 inline LL query(int x, int y)
     84 {
     85     int i, l = belong[x], r = belong[y];
     86     LL ans = 0;
     87     if(l == r)
     88     {
     89         for(i = x; i <= y; i++)
     90             ans = (ans + a[i] * mul[l] + add[l]) % p;
     91         return ans;
     92     }
     93     for(i = x; i <= ed[l]; i++)
     94         ans = (ans + a[i] * mul[l] + add[l]) % p;
     95     for(i = l + 1; i <= r - 1; i++)
     96         ans = (ans + sum[i] * mul[i] + add[i] * (ed[i] - st[i] + 1)) % p;
     97     for(i = st[r]; i <= y; i++)
     98         ans = (ans + a[i] * mul[r] + add[r]) % p;
     99     return ans;
    100 }
    101 
    102 inline void work()
    103 {
    104     int i, x, y, z;
    105     LL k;
    106     for(i = 1; i <= m; i++)
    107     {
    108         scanf("%d %d %d", &z, &x, &y);
    109         if(z == 3) printf("%lld
    ", query(x, y));
    110         else scanf("%lld", &k), update(z, x, y, k);
    111     }
    112 }
    113 
    114 int main()
    115 {
    116     init();
    117     work();
    118     return 0;
    119 }
    View Code

    还有一个链接,黄学长的分块姿势。

    【分块】数列分块入门1-9 by hzwer

  • 相关阅读:
    Python中CreateCompatibleDC和CreateBitmap造成的内存泄漏
    POJ 2420 模拟退火
    LR(1)分析表-语法树-四元式
    C语言文法
    计蒜客 18018 热爱工作的蒜蒜 最短路+dp
    HDU 5988 最小费用流
    POJ 1808 平方剩余
    POJ 2115 单变元模线性方程
    计蒜客 17414 Exponial 指数降幂公式
    计蒜客 17412 Card Hand Sorting 最长公共子序列
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6823943.html
Copyright © 2011-2022 走看看