• 【BZOJ1798】【Ahoi2009】Seq 维护序列(线段树)


    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798

    唔这是好久好久以前写不出的题了QAQ,就是一个线段树水题qvq

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 #define MaxN 100010
     7 #define MaxM 200010
     8 #define LL long long
     9 using namespace std;
    10 LL p, ans;
    11 int n, m, root = 0, S = 0, L, R;
    12 int ch[MaxM][2], da[MaxN];
    13 LL sz[MaxM], mu[MaxM], ad[MaxM], sum[MaxM], val[MaxM]; 
    14 
    15 #define l ch[x][0]
    16 #define r ch[x][1]
    17 #define mid (a+b) / 2
    18 
    19 void updata(int x, LL multi, LL add){
    20     if (!x) return;
    21     sum[x] = (sum[x] * multi % p + sz[x] * add) % p;
    22     ad[x] = (ad[x] * multi + add) % p;
    23     mu[x] = (mu[x] * multi) % p;
    24 }
    25 
    26 void push_up(int x){
    27     sum[x] = (sum[l] + sum[r]) % p;
    28 }
    29 
    30 void push_down(int x){
    31     LL MU = mu[x], AD = ad[x];
    32     if (MU != 1ll || AD != 0ll){
    33         updata(l, MU, AD); updata(r, MU, AD);
    34         mu[x] = 1ll; ad[x] = 0ll; 
    35     }
    36 }
    37 
    38 void Build(int &x, int a, int b){
    39     x = ++S;
    40     mu[x] = 1ll, ad[x] = 0ll;
    41     if (a == b) { sum[x] = (LL)da[a]; sz[x] = 1ll; return; }
    42     Build(ch[x][0], a, mid);
    43     Build(ch[x][1], mid+1, b);
    44     sz[x] = sz[ch[x][0]] + sz[ch[x][1]];
    45     push_up(x);
    46 }
    47 
    48 void query(int x, int a, int b){
    49     push_down(x);
    50     if (L <= a && R >= b) {
    51         ans = (ans + sum[x]) % p;
    52         return ;
    53     }
    54     if (L <= mid) query(l, a, mid);
    55     if (R > mid) query(r, mid+1, b);
    56     push_up(x);
    57 }
    58 
    59 void change(int x, int a, int b, LL c, int q){
    60     push_down(x);
    61     if (L <= a && R >= b) {
    62         if (q == 1) updata(x, c, 0ll);
    63         else updata(x, 1ll, c);
    64         return ;
    65     }
    66     if (L <= mid) change(l, a, mid, c, q);
    67     if (R > mid) change(r, mid+1, b, c, q);
    68     push_up(x);
    69 }
    70 
    71 int main(){
    72     int q, c;
    73     scanf("%d%lld", &n, &p);
    74     for (int i = 1; i <= n; i++) scanf("%d", &da[i]);
    75     memset(mu, 1ll, sizeof(mu));
    76     Build(root, 1, n);
    77     scanf("%d", &m);
    78     for (int i = 1; i <= m; i++) {
    79         scanf("%d%d%d", &q, &L, &R);
    80         if (q != 3) {
    81             scanf("%d", &c);
    82             change(root, 1, n, (LL)c, q);
    83         }
    84         else ans = 0ll, query(root, 1, n), printf("%lld
    ", ans);
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    矩阵求逆的几种方法总结(C++)
    c++ 继承类强制转换时的虚函数表工作原理
    博客开通(附本博客样式)
    Python-SocketServer模块
    Python-UDP编程
    Python-TCP编程
    Python-logging模块
    Python-多线程+多进程包(concurrent包,处理并发)
    07数组与接口
    java作业 06
  • 原文地址:https://www.cnblogs.com/Lukaluka/p/5152276.html
Copyright © 2020-2023  润新知