zoukankan      html  css  js  c++  java
  • Transformation

    http://acm.hdu.edu.cn/showproblem.php?pid=4578

    题意:

    含n个数字的的数列a各数字初值均为0,对其进行m次操作,每次操作可为下列之一:

    1 x y c:ax到ay间的数字(含边界)均增加c

    2 x y c:ax到ay间的数字(含边界)均乘以c

    3 x y c:ax到ay间的数字(含边界)均变为c

    4 x y p:输出ax到ay间的数字(含边界)的p次方之和

    对于每个操作4,输出答案模10007

    数据组数<=10。

    1<=n,m<=1e5,1<=x<=y<=n,1<=c<=1e4,1<=p<=3

    输入 0 0结束

    解法:

    有特意限制p就是水题了

    假如p = 1那么显然就是普通的线段树

    当p = 2或者p = 3的时候,第2、3种操作依然比较好处理

    而对于第一种,我们列个求和公式就能发现更新其实很方便的

    线段树里s[i]代表该线段覆覆盖元素的 i 次方之和

    更新很简单(自己列求和公式想不出来就参照代码里pushdown函数吧

    实现:

    脑抽了没有线段树没有开s数组而是直接申请了三个变量s1,s2,s3

    实际证明完全是给自己找麻烦

    手残居然磨磨唧唧写了1h...

    还WA了...又改了1h

    改错:

    其实最难的地方在于三个标记的优先顺序

    首先有覆盖标记,就下传并把儿子的加法标记和乘法标记改为0和1

    其次看乘法标记,乘法标记需要更新儿子的加法标记

    最后看加法标记

    二逼错误:

    1.打上覆盖标记后,乘法标记更新为1...乘法标记更新为1不是0!

    2.我的ask函数的返回值没有取膜...我可能是脑残吧

      1 #include <cstdio>
      2 
      3 #define lc (o << 1)
      4 #define rc (o << 1 | 1)
      5 
      6 typedef long long ll;
      7 
      8 const int Mod = 10007;
      9 const int maxn = 100010;
     10 
     11 struct node {
     12     ll s1, s2, s3;
     13     ll laza, lazm, lazc;
     14     void clear() {
     15         s1 = s2 = s3 = 0;
     16         laza = lazc = 0;
     17         lazm = 1;
     18     }
     19 }tr[maxn << 2];
     20 
     21 ll z;
     22 int Case, n, m, x, y, op;
     23 
     24 void pushup(int o) {
     25     tr[o].s1 = tr[lc].s1 + tr[rc].s1; 
     26     tr[o].s2 = tr[lc].s2 + tr[rc].s2;
     27     tr[o].s3 = tr[lc].s3 + tr[rc].s3;
     28 }
     29 
     30 void pushdown(int o, int l, int r) {
     31     int mid = (l + r) >> 1;
     32     if(tr[o].lazc) {
     33         tr[lc].s3 = tr[o].lazc * tr[o].lazc * tr[o].lazc * (mid - l + 1)  % Mod;
     34         tr[rc].s3 = tr[o].lazc * tr[o].lazc * tr[o].lazc * (r - mid)  % Mod;
     35         tr[lc].s2 = tr[o].lazc * tr[o].lazc * (mid - l + 1) % Mod; 
     36         tr[rc].s2 = tr[o].lazc * tr[o].lazc * (r - mid) % Mod;
     37         tr[lc].s1 = tr[o].lazc * (mid - l + 1) % Mod; 
     38         tr[rc].s1 = tr[o].lazc * (r - mid) % Mod; 
     39         tr[lc].lazc = tr[rc].lazc = tr[o].lazc;
     40         tr[lc].laza = tr[rc].laza = 0;
     41         tr[lc].lazm = tr[rc].lazm = 1;
     42         tr[o].lazc = 0;    
     43     }
     44     if(tr[o].lazm != 1) {
     45         tr[lc].s3 = (tr[lc].s3 * tr[o].lazm * tr[o].lazm * tr[o].lazm) % Mod;
     46         tr[rc].s3 = (tr[rc].s3 * tr[o].lazm * tr[o].lazm * tr[o].lazm) % Mod;
     47         tr[lc].s2 = (tr[lc].s2 * tr[o].lazm * tr[o].lazm) % Mod;
     48         tr[rc].s2 = (tr[rc].s2 * tr[o].lazm * tr[o].lazm) % Mod;
     49         tr[lc].s1 = (tr[lc].s1 * tr[o].lazm) % Mod;
     50         tr[rc].s1 = (tr[rc].s1 * tr[o].lazm) % Mod;
     51         tr[lc].laza = (tr[lc].laza * tr[o].lazm) % Mod;
     52         tr[rc].laza = (tr[rc].laza * tr[o].lazm) % Mod;
     53         tr[lc].lazm = (tr[lc].lazm * tr[o].lazm) % Mod;
     54         tr[rc].lazm = (tr[rc].lazm * tr[o].lazm) % Mod;
     55         tr[o].lazm = 1;
     56     }
     57     if(tr[o].laza) {
     58         tr[lc].s3 = (tr[lc].s3 + tr[o].laza * tr[lc].s2 * 3 + tr[o].laza * tr[o].laza * tr[lc].s1 * 3 + tr[o].laza * tr[o].laza * tr[o].laza * (mid - l + 1)) % Mod;
     59         tr[rc].s3 = (tr[rc].s3 + tr[o].laza * tr[rc].s2 * 3 + tr[o].laza * tr[o].laza * tr[rc].s1 * 3 + tr[o].laza * tr[o].laza * tr[o].laza * (r - mid)) % Mod;
     60         tr[lc].s2 = (tr[lc].s2 + tr[o].laza * tr[lc].s1 * 2 + tr[o].laza * tr[o].laza * (mid - l + 1)) % Mod;
     61         tr[rc].s2 = (tr[rc].s2 + tr[o].laza * tr[rc].s1 * 2 + tr[o].laza * tr[o].laza * (r - mid)) % Mod;
     62         tr[lc].s1 = (tr[lc].s1 + tr[o].laza * (mid - l + 1)) % Mod;
     63         tr[rc].s1 = (tr[rc].s1 + tr[o].laza * (r - mid)) % Mod;
     64         tr[lc].laza = (tr[lc].laza + tr[o].laza) % Mod;
     65         tr[rc].laza = (tr[rc].laza + tr[o].laza) % Mod;
     66         tr[o].laza = 0;
     67     }
     68 }
     69 
     70 void build(int o, int l, int r) {
     71     tr[o].clear();
     72     if(l == r) return;
     73     int mid = (l + r) >> 1;
     74     build(lc, l, mid);
     75     build(rc, mid + 1, r);
     76 }
     77 
     78 void add(int o, int l, int r) {
     79     if(l != r) pushdown(o, l, r);
     80     if(x <= l && r <= y) {
     81         tr[o].s3 = (tr[o].s3 + z * tr[o].s2 * 3 + z * z * tr[o].s1 * 3 + z * z * z * (r - l + 1)) % Mod;
     82         tr[o].s2 = (tr[o].s2 + z * tr[o].s1 * 2 + z * z * (r - l + 1)) % Mod;
     83         tr[o].s1 = (tr[o].s1 + z * (r - l + 1)) % Mod;
     84         tr[o].laza = (tr[o].laza + z) % Mod;
     85         return;
     86     }
     87     int mid = (l + r) >> 1;
     88     if(x <= mid) add(lc, l, mid);
     89     if(y >  mid) add(rc, mid + 1, r);
     90     pushup(o);
     91 }
     92 
     93 void multiply(int o, int l, int r) {
     94     if(l != r) pushdown(o, l, r);
     95     if(x <= l && r <= y) {
     96         tr[o].s3 = (tr[o].s3 * z * z * z) % Mod;
     97         tr[o].s2 = (tr[o].s2 * z * z) % Mod;
     98         tr[o].s1 = (tr[o].s1 * z) % Mod;
     99         tr[o].lazm = (tr[o].lazm * z) % Mod;
    100         return;
    101     }
    102     int mid = (l + r) >> 1;
    103     if(x <= mid) multiply(lc, l, mid);
    104     if(y >  mid) multiply(rc, mid + 1, r);
    105     pushup(o);
    106 }
    107 
    108 void cover(int o, int l, int r) {
    109     if(l != r) pushdown(o, l, r);
    110     if(x <= l && r <= y) {
    111         tr[o].s3 = z * z * z * (r - l + 1)  % Mod;
    112         tr[o].s2 = z * z * (r - l + 1) % Mod; 
    113         tr[o].s1 = z * (r - l + 1) % Mod; 
    114         tr[o].lazc = z;    
    115         return;
    116     }
    117     int mid = (l + r) >> 1;
    118     if(x <= mid) cover(lc, l, mid);
    119     if(y >  mid) cover(rc, mid + 1, r);
    120     pushup(o);
    121 }
    122 
    123 ll ask(int o, int l, int r) {
    124     if(l != r) pushdown(o, l, r);
    125     if(x <= l && r <= y) {
    126         switch(z) {
    127             case 1:return tr[o].s1;
    128             case 2:return tr[o].s2;
    129             case 3:return tr[o].s3;
    130         }
    131     }
    132     ll res = 0;
    133     int mid = (l + r) >> 1;
    134     if(x <= mid) res += ask(lc, l, mid);
    135     if(y >  mid) res += ask(rc, mid + 1, r);
    136     return res % Mod;
    137 }
    138 
    139 int main() {
    140     while(scanf("%d %d", &n, &m), n != 0) {
    141         build(1, 1, n);
    142         while(m --) {
    143             scanf("%d %d %d %lld", &op, &x, &y, &z);
    144             switch(op) {
    145                 case 1:add(1, 1, n);break;
    146                 case 2:multiply(1, 1, n);break;
    147                 case 3:cover(1, 1, n);break;
    148                 case 4:printf("%lld
    ", ask(1, 1, n));break;
    149             }
    150         }
    151     }
    152     return 0;
    153 }
    View Code
  • 相关阅读:
    pycharm如何快速替换代码中的字符
    tcp三次握手四次挥手那些事
    Python之异常处理
    Python之单例模式
    ApplicationContext
    ContextLoaderListener作用详解
    DispatcherServlet--Spring的前置控制器作用简介
    web.xml中servlet的配置
    Hibernate各种主键生成策略与配置详解【附1--<generator class="foreign">】
    java.util.ConcurrentModificationException 解决办法(转)
  • 原文地址:https://www.cnblogs.com/ytytzzz/p/6629360.html
Copyright © 2011-2022 走看看