zoukankan      html  css  js  c++  java
  • 线段树懒标记好题 HDU4578

    (1)"1 x y c",代表 把区间 [x,y] 上的值全部加c

    (2)"2 x y c",代表 把区间 [x,y] 上的值全部乘以c

    (3)"3 x y c" 代表 把区间 [x,y]上的值全部赋值为c

    (4)"4 x y p" 代表 求区间 [x,y] 上值的p次方和1<=p<=3

    维护sum1[], sum2[], sum3[]分别为一次方、二次方、三次方的和

          因为P只有1到3,(x+c)^2=(x^2)+(2*x*c+c^2),即我们可以从一次方和的结果推出二次方的和的结果。同理,我们也可以根据一次方的和的结果,二次方和的结果推出三次方和的结果。这样,我们可以用几个懒标记去记录这几个操作。但是这题明白上面这点还是不够的,因为,这几种更新操作之间会相互影响,比如对一个区间进行操作3之后,那么操作1和2就失效了。因此在PushDown传递懒标记的时候,传递的顺序也是重要的。

      1 #include <bits/stdc++.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <stdio.h>
      5 #define pb push_back
      6 #define fi first
      7 #define se second
      8 #define lson(r) (r<<1)
      9 #define rson(r) ((r<<1)|1)
     10 
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 
     15 const int MAXN = 1e5+7;
     16 const int MAXV = 507;
     17 const int MAXE = 507;
     18 const ll MOD = 10007;
     19 ll sum1[MAXN << 2];
     20 ll sum2[MAXN << 2];
     21 ll sum3[MAXN << 2];
     22 ll addmark[MAXN << 2];
     23 ll setmark[MAXN << 2];
     24 ll mulmark[MAXN << 2];
     25 
     26 void pushDown(int root, int l, int r)
     27 {
     28     int num = (r-l+1);
     29     ll numr = num >> 1;
     30     ll numl = num - numr;
     31     //思考了半天用-1还是不够优秀呀 只需要把另外优先级低的懒标记 标记的左右子即可 
     32     //修改了半天 哎哎哎 这道题目深入理解懒标记
     33     if (setmark[root])
     34     {
     35         ll setval = setmark[root];
     36         //cout << "set" << l << " " << r << " " << setmark[root] << endl;
     37         sum1[lson(root)] = (numl*setval) % MOD;
     38         sum1[rson(root)] = (numr*setval) % MOD;
     39         sum2[lson(root)] = (numl*setval*setval) % MOD;
     40         sum2[rson(root)] = (numr*setval*setval) % MOD;
     41         sum3[lson(root)] = (numl*setval*setval*setval) % MOD;
     42         sum3[rson(root)] = (numr*setval*setval*setval) % MOD;
     43         setmark[lson(root)] = setval;
     44         setmark[rson(root)] = setval;
     45         addmark[lson(root)] = addmark[rson(root)] = 0;
     46         mulmark[lson(root)] = mulmark[rson(root)] = 1;
     47         setmark[root] = 0;
     48     }
     49     if (mulmark[root] != 1)
     50     {
     51         ll mulval = mulmark[root];
     52         sum1[lson(root)] = (sum1[lson(root)]*mulval) % MOD;
     53         sum1[rson(root)] = (sum1[rson(root)]*mulval) % MOD;
     54         sum2[lson(root)] = (sum2[lson(root)]*mulval*mulval) % MOD;
     55         sum2[rson(root)] = (sum2[rson(root)]*mulval*mulval) % MOD;
     56         sum3[lson(root)] = (sum3[lson(root)]*mulval*mulval*mulval) % MOD;
     57         sum3[rson(root)] = (sum3[rson(root)]*mulval*mulval*mulval) % MOD;
     58         mulmark[lson(root)] = (mulmark[lson(root)]*mulval) % MOD;
     59         mulmark[rson(root)] = (mulmark[rson(root)]*mulval) % MOD;
     60         addmark[lson(root)] = (addmark[lson(root)]*mulval) % MOD;
     61         addmark[rson(root)] = (addmark[rson(root)]*mulval) % MOD;
     62         mulmark[root] = 1;
     63     }    
     64     if (addmark[root])
     65     {
     66         ll addval = addmark[root];
     67         sum3[lson(root)] = ((sum3[lson(root)]+numl*addval*addval*addval)%MOD+(3*sum2[lson(root)]*addval+3*sum1[lson(root)]*addval*addval)%MOD)%MOD;
     68         sum3[rson(root)] = ((sum3[rson(root)]+numr*addval*addval*addval)%MOD+(3*sum2[rson(root)]*addval+3*sum1[rson(root)]*addval*addval)%MOD)%MOD;
     69         sum2[lson(root)] = (((sum2[lson(root)] + numl*addval*addval) % MOD) + (2*sum1[lson(root)]*addval)) % MOD;
     70         sum2[rson(root)] = (((sum2[rson(root)] + numr*addval*addval) % MOD) + (2*sum1[rson(root)]*addval)) % MOD;
     71         sum1[lson(root)] = (sum1[lson(root)] + numl * addval) % MOD;
     72         sum1[rson(root)] = (sum1[rson(root)] + numr * addval) % MOD;
     73         addmark[lson(root)] = (addmark[lson(root)] + addval) % MOD;
     74         addmark[rson(root)] = (addmark[rson(root)] + addval) % MOD;
     75         addmark[root] = 0;
     76     }
     77 }
     78 void update(int root, int l, int r, int ul, int ur, int mathod, ll val)
     79 {
     80     if (l > ur || r < ul) return ;
     81     if (l >= ul && r <= ur)
     82     {
     83         ll num = r-l+1;
     84         if (mathod == 1)
     85         {
     86             //cout << l << " " << r << " " << val << endl;
     87             setmark[root] = val%MOD;
     88             addmark[root] = 0;
     89             mulmark[root] = 1;
     90             sum1[root] = (num*val) % MOD;
     91             sum2[root] = (num*val*val) % MOD;
     92             sum3[root] = (num*val*val*val) % MOD;
     93         }
     94         else if (mathod == 2)
     95         {
     96             mulmark[root] = (mulmark[root]*val)%MOD;
     97             addmark[root] = (val*addmark[root])%MOD;
     98             sum1[root] = (sum1[root]*val) % MOD;
     99             sum2[root] = (sum2[root]*val*val) % MOD;
    100             sum3[root] = (sum3[root]*val*val*val) % MOD;
    101         }
    102         else if (mathod == 3)
    103         {
    104 
    105             //cout << l << " "  << r << " " << sum1[root] << endl;
    106             addmark[root] = (addmark[root]+val)%MOD;
    107             sum3[root] = ((sum3[root]+num*val*val*val)%MOD+(3*sum2[root]*val+3*sum1[root]*val*val)%MOD)%MOD;
    108             sum2[root] = ((sum2[root] + num*val*val) % MOD + (2*sum1[root]*val)) % MOD;
    109             sum1[root] = (sum1[root] + num * val) % MOD;
    110             //cout << l << " "  << r << " " << sum1[root] << endl;
    111         }
    112         return ;
    113     }
    114     pushDown(root, l, r);
    115     int mid = (l+r) >> 1;
    116     if (ul <= mid) update(lson(root), l, mid, ul, ur, mathod, val);
    117     if (ur > mid) update(rson(root), mid+1, r, ul, ur, mathod, val);
    118     sum1[root] = (sum1[lson(root)] + sum1[rson(root)]) % MOD;
    119     sum2[root] = (sum2[lson(root)] + sum2[rson(root)]) % MOD;
    120     sum3[root] = (sum3[lson(root)] + sum3[rson(root)]) % MOD;
    121     //cout << l << " " << r << " " << sum1[root] << endl;
    122 }
    123 
    124 int cnt = 0;
    125 ll query(int root, int l, int r, int ql, int qr, int p)
    126 {
    127    // cout << l << " " << r << endl;
    128     if (l > qr || r < ql) return 0;
    129     if (l >= ql && r <= qr)
    130     {
    131         if (p == 1) return sum1[root];
    132         else if (p == 2) return sum2[root];
    133         else if (p == 3) return sum3[root];
    134     }
    135     pushDown(root, l, r);
    136     int mid = (l+r) >> 1;
    137     ll res = 0;
    138     if (ql <= mid) res = (res + query(lson(root), l, mid, ql, qr, p)) % MOD;
    139     if (qr >= mid+1) res = (res + query(rson(root), mid+1, r, ql, qr, p)) % MOD; 
    140     return res;
    141 }
    142 int n, m;
    143 int main()
    144 {
    145    // freopen("in.txt", "r", stdin);
    146     while (~scanf("%d%d", &n, &m))
    147     {
    148         for(int i = 0; i < MAXN << 2; i++) mulmark[i] = 1;
    149         if (!n && !m) break;
    150         memset(addmark, 0, sizeof(addmark));
    151         //memset(mulmark, 1, sizeof(mulmark));
    152         memset(setmark, 0, sizeof(setmark));
    153         memset(sum1, 0, sizeof(sum1));
    154         memset(sum2, 0, sizeof(sum2));
    155         memset(sum3, 0, sizeof(sum3));
    156         for (int i = 0; i < m; i++)
    157         {
    158             int op, l, r, c;
    159             scanf("%d%d%d%d", &op, &l, &r, &c);
    160             if (op == 1) 
    161             {
    162                 update(1, 1, n, l, r, 3, c);            
    163             }
    164             else if (op == 2) 
    165             {
    166                 update(1, 1, n, l, r, 2, c);
    167             }
    168             else if (op == 3) 
    169             {
    170                 update(1, 1, n, l, r, 1, c);
    171             }
    172             else 
    173             {
    174                 ll ans = query(1, 1, n, l, r, c);
    175                 cout << ans << endl;
    176             }
    177         }
    178     }
    179     return 0;
    180 }
  • 相关阅读:
    读入输出优化
    码表
    windows下bat批处理实现守护进程(有日志)
    cmd批处理常用符号详解
    批处理之 for/f 详解
    WINDOWS XP中用命令行管理用户 net user命令
    VacmMIB
    工作遇到
    snmp之GenericAddress
    snmp4j 之 ArgumentParser
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/8799157.html
Copyright © 2011-2022 走看看