zoukankan      html  css  js  c++  java
  • HDU 4578 Transformation

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4578

    ----------------------------------------------------------------------------------

    一道操作比较复杂的线段树的题目

    强烈建议线段树写得比较少的同学把操作$1,2,3$一个一个地加上去

    直接写三个操作思路可能比较乱

    这题是求区间$1$到$3$次方的和 对于1操作 需要推导下如何更新

    假设区间长度为$len 1,2,3 $次方的和分别为$ sum1$ $sum2$ $sum3$

    更新后为$ sum1'$ $sum2'$ $sum3' $那么

    $sum1' = sum1 + c * len$

    $sum2' = sum2 + sum1 * c * 2 +  c * c * len$

    $sum3' = sum3 + sum2 * c * 3 + sum1 * c * c * 3 + c * c * c * len$

    其他部分都还好 就是要耐心一点去分析 代码量只有$2K+$

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <algorithm>
      5 using namespace std;
      6 const int N = 100010, mod = 10007;
      7 int sum[3][N << 2], flag[3][N << 2];
      8 int n, m;
      9 void update(int x, int L, int R, int tl, int tr, int o, int c);
     10 void build(int x, int tl, int tr)
     11 {
     12     sum[0][x] = sum[1][x] = sum[2][x] = 0;
     13     flag[0][x] = flag[2][x] = 0;
     14     flag[1][x] = 1;
     15     if(tl == tr)
     16         return;
     17     int mid = (tl + tr) >> 1;
     18     build(x << 1, tl, mid);
     19     build(x << 1 | 1, mid + 1, tr);
     20 }
     21 void pushdown(int x, int tl, int tr)
     22 {
     23     int mid = (tl + tr) >> 1;
     24     for(int i = 2; i >= 0; --i)
     25         if(flag[i][x] && !(i == 1 && flag[i][x] == 1))
     26         {
     27             update(x << 1, tl, mid, tl, mid, i, flag[i][x]);
     28             update(x << 1 | 1, mid + 1, tr, mid + 1, tr, i, flag[i][x]);
     29             flag[i][x] = (i == 1 ? 1 : 0);
     30         }
     31 }
     32 void update(int x, int L, int R, int tl, int tr, int o, int c)
     33 {
     34     int mid = (tl + tr) >> 1;
     35     if(L <= tl && tr <= R)
     36     {
     37         if(o == 0)
     38         {
     39             flag[0][x] = (flag[0][x] + c) % mod;
     40             sum[2][x] = (sum[2][x] + sum[1][x] * c * 3 % mod
     41             + sum[0][x] * c % mod * c * 3 % mod + c * c % mod * c % mod * 
     42             (tr - tl + 1) % mod) % mod;
     43             sum[1][x] = (sum[1][x] + sum[0][x] * c * 2 % mod + c * c % mod *
     44             (tr - tl + 1) % mod) % mod;
     45             sum[0][x] = (sum[0][x] + c * (tr - tl + 1) % mod) % mod; 
     46         }
     47         else if(o == 1)
     48         {
     49             flag[0][x] = flag[0][x] * c % mod;
     50             flag[1][x] = flag[1][x] * c % mod;
     51             sum[0][x] = sum[0][x] * c % mod;
     52             sum[1][x] = sum[1][x] * c % mod * c % mod;
     53             sum[2][x] = sum[2][x] * c % mod * c % mod * c % mod;
     54         }
     55         else
     56         {
     57             flag[0][x] = 0;
     58             flag[1][x] = 1;
     59             flag[2][x] = c;
     60             sum[0][x] = (tr - tl + 1) * c % mod;
     61             sum[1][x] = (tr - tl + 1) * c % mod * c % mod;
     62             sum[2][x] = (tr - tl + 1) * c % mod * c % mod * c % mod;
     63         }
     64         return;
     65     }
     66     pushdown(x, tl, tr);
     67     if(L <= mid)
     68         update(x << 1, L, R, tl, mid, o, c);
     69     if(mid < R)
     70         update(x << 1 | 1, L, R, mid + 1, tr, o, c);
     71     for(int i = 0; i < 3; ++i)
     72         sum[i][x] = (sum[i][x << 1] + sum[i][x << 1 | 1]) % mod;
     73 }
     74 int query(int x, int L, int R, int tl, int tr, int p)
     75 {
     76     if(L <= tl && tr <= R)
     77         return sum[p][x];
     78     pushdown(x, tl, tr);
     79     int mid = (tl + tr) >> 1, re= 0;
     80     if(L <= mid)
     81         re += query(x << 1, L, R, tl, mid, p);
     82     if(mid < R)
     83         re += query(x << 1 | 1, L, R, mid + 1, tr, p);
     84     return re % mod;
     85 }
     86 int main()
     87 {
     88     while(scanf("%d%d", &n, &m),n)
     89     {
     90         build(1, 1, n);
     91         int o, x, y, c;
     92         while(m--)
     93         {
     94             scanf("%d%d%d%d", &o, &x, &y, &c);
     95             if(o != 4)
     96                 update(1, x, y, 1, n, o - 1, c);
     97             else
     98                 printf("%d
    ", query(1, x, y, 1, n, c - 1));
     99         }
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    HashMap源码分析
    静态代理和装饰模式的区别
    自动内存管理
    ReentrantReadWriteLock
    ReentranLock
    对象的内存布局
    对象的创建
    [P2495][SDOI2011]消耗战——虚树
    [HDU2966]In case of failure——KD树
    [Gym-101158J]Coverthe Polygon with Your Disk——梯度下降,模拟退火
  • 原文地址:https://www.cnblogs.com/sagitta/p/5183988.html
Copyright © 2011-2022 走看看