zoukankan      html  css  js  c++  java
  • hdu 4578 Transformation 线段树

    区间加,区间乘,区间修改,区间1到3次方和查询。

    (x + a)^2 = x^2 + ax + a^2

    (x + a)^3 = x^3 + a^2x + ax^2 + a^3

    所以我们发现3次方和再涉及到加法修改时,可以由2次方和推出。2次方和涉及到加法修改时,可以由一次方和推出。

    乘法修改更简单,直接乘上对应次数的a即可。

    而修改值也很简单,直接改成新值的对应平方和即可。

    lzy标记是,修改值最高,乘法优先度其次,加法次之。

    修改值lzy下传时,直接删除掉其他的lzy即可,并维护新的修改值lzy即可。跟19年上海的题好像啊。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <cmath>
      5 using namespace std;
      6 #define int long long
      7 int sum[4][810000],lzy[3][810000],vec[210000];
      8 int n,m;
      9 const int mo = 10007;
     10 void up(int k)
     11 {
     12     for (int i = 1;i <= 3;i++)
     13         sum[i][k] = (sum[i][k << 1] + sum[i][k << 1 | 1]) % mo;
     14 }
     15 void build(int k,int l,int r)
     16 {
     17     lzy[0][k] = 0;
     18     lzy[1][k] = 0;
     19     lzy[2][k] = 1;
     20     if (l == r)
     21     {
     22         sum[1][k] = vec[l] % mo;
     23         sum[2][k] = sum[1][k] * vec[l] % mo;
     24         sum[3][k] = sum[2][k] * vec[l] % mo;
     25         return;
     26     }
     27     int mid = l + r >> 1;
     28     build(k << 1,l,mid);
     29     build(k << 1 | 1,mid + 1,r);
     30     up(k);
     31 }
     32 void down(int k,int l,int r)
     33 {
     34     if (l == r)
     35     {
     36         lzy[2][k] = 1;
     37         lzy[1][k] = 0;
     38         lzy[0][k] = 0;
     39         return;
     40     }
     41     int mid = l + r >> 1;
     42     if (lzy[0][k] != 0)
     43     {
     44         sum[1][k << 1] = (mid - l + 1) % mo * lzy[0][k] % mo;
     45         sum[1][k << 1 | 1] = (r - mid) % mo * lzy[0][k] % mo;
     46         sum[2][k << 1] = sum[1][k << 1] * lzy[0][k] % mo;
     47         sum[2][k << 1 | 1] = sum[1][k << 1 | 1] * lzy[0][k] % mo;
     48         sum[3][k << 1] = sum[2][k << 1] * lzy[0][k] % mo;
     49         sum[3][k << 1 | 1] = sum[2][k << 1 | 1] * lzy[0][k] % mo;
     50         lzy[0][k << 1] = lzy[0][k << 1 | 1] = lzy[0][k];
     51         lzy[1][k << 1] = lzy[1][k << 1 | 1] = 0;
     52         lzy[2][k << 1] = lzy[2][k << 1 | 1] = 1;
     53         lzy[0][k] = 0;
     54     }
     55     if (lzy[2][k] != 1)
     56     {
     57         sum[1][k << 1] = sum[1][k << 1] * lzy[2][k] % mo;
     58         sum[2][k << 1] = sum[2][k << 1] * lzy[2][k] % mo * lzy[2][k] % mo;
     59         sum[3][k << 1] = sum[3][k << 1] * lzy[2][k] % mo * lzy[2][k] % mo * lzy[2][k] % mo;
     60         sum[1][k << 1 | 1] = sum[1][k << 1 | 1] * lzy[2][k] % mo;
     61         sum[2][k << 1 | 1] = sum[2][k << 1 | 1] * lzy[2][k] % mo * lzy[2][k] % mo;
     62         sum[3][k << 1 | 1] = sum[3][k << 1 | 1] * lzy[2][k] % mo * lzy[2][k] % mo * lzy[2][k] % mo;
     63         lzy[2][k << 1] = lzy[2][k << 1] * lzy[2][k] % mo;
     64         lzy[2][k << 1 | 1] = lzy[2][k << 1 | 1] * lzy[2][k] % mo;
     65         lzy[1][k << 1] = lzy[1][k << 1] * lzy[2][k] % mo;
     66         lzy[1][k << 1 | 1] = lzy[1][k << 1 | 1] * lzy[2][k] % mo;
     67         lzy[2][k] = 1;
     68     }
     69     if (lzy[1][k] != 0)
     70     {
     71         sum[3][k << 1] = ((((sum[3][k << 1] + sum[2][k << 1] * lzy[1][k] % mo * 3 % mo) % mo + sum[1][k << 1] * lzy[1][k] % mo * lzy[1][k] % mo * 3 % mo) % mo) + lzy[1][k] * lzy[1][k] % mo * lzy[1][k] % mo * (mid - l + 1) % mo) % mo;
     72         sum[2][k << 1] = ((sum[2][k << 1] + lzy[1][k] * lzy[1][k] % mo * (mid - l + 1) % mo) % mo + lzy[1][k] * sum[1][k << 1] % mo  * 2 % mo) % mo;
     73         sum[1][k << 1] = (sum[1][k << 1] + lzy[1][k] * (mid - l + 1) % mo) % mo;
     74         sum[3][k << 1 | 1] = ((((sum[3][k << 1 | 1] + sum[2][k << 1 | 1] * lzy[1][k] % mo * 3 % mo) % mo + sum[1][k << 1 | 1] * lzy[1][k] % mo * lzy[1][k] % mo * 3 % mo) % mo) + lzy[1][k] * lzy[1][k] % mo * lzy[1][k] % mo * (r - mid) % mo) % mo;
     75         sum[2][k << 1 | 1] = ((sum[2][k << 1 | 1] + lzy[1][k] * lzy[1][k] % mo * (r - mid) % mo) % mo + lzy[1][k] * sum[1][k << 1 | 1] % mo  * 2 % mo) % mo;
     76         sum[1][k << 1 | 1] = (sum[1][k << 1 | 1] + lzy[1][k] * (r - mid) % mo) % mo;
     77         lzy[1][k << 1] = (lzy[1][k << 1] + lzy[1][k]) % mo;
     78         lzy[1][k << 1 | 1] = (lzy[1][k << 1 | 1] + lzy[1][k]) % mo;
     79         lzy[1][k] = 0;
     80     }
     81 }
     82   
     83 int query(int k,int l,int r,int x,int y,int v)
     84 {
     85     if (x <= l && r <= y)
     86         return sum[v][k];
     87     down(k,l,r);
     88     int mid = l + r >> 1,res = 0;
     89     if (x <= mid)
     90         res = (res + query(k << 1,l,mid,x,y,v)) % mo;
     91     if (y >= mid + 1)
     92         res = (res + query(k << 1 | 1,mid + 1,r,x,y,v)) % mo;
     93     up(k);
     94     return res;
     95 }
     96 void add(int k,int l,int r,int x,int y,int ad)
     97 {
     98     down(k,l,r);
     99     if (x <= l && r <= y)
    100     {
    101         sum[3][k] = ((((sum[3][k] + sum[2][k] * ad % mo * 3 % mo) % mo + sum[1][k] * ad % mo * ad % mo * 3 % mo) % mo) + ad * ad % mo * ad % mo * (r - l + 1) % mo) % mo;
    102         sum[2][k] = ((sum[2][k] + ad * ad % mo * (r - l + 1) % mo) % mo + ad * sum[1][k] % mo * 2 % mo) % mo;
    103         sum[1][k] = (sum[1][k] + ad * (r - l + 1) % mo) % mo;
    104         lzy[1][k] = (lzy[1][k] + ad) % mo;
    105         return;
    106     }
    107     int mid = l + r >> 1;
    108     if (x <= mid)
    109         add(k << 1,l,mid,x,y,ad);
    110     if (y >= mid + 1)
    111         add(k << 1 | 1,mid + 1,r,x,y,ad);
    112     up(k);
    113 }
    114 void mul(int k,int l,int r,int x,int y,int mu)
    115 {
    116     down(k,l,r);
    117     if (x <= l && r <= y)
    118     {
    119         sum[1][k] = sum[1][k] * mu % mo;
    120         sum[2][k] = sum[2][k] * mu % mo * mu % mo;
    121         sum[3][k] = sum[3][k] * mu % mo * mu % mo * mu % mo;
    122         lzy[2][k] = lzy[2][k] * mu % mo;
    123         return;
    124     }
    125     int mid = l + r >> 1;
    126     if (x <= mid)
    127         mul(k << 1,l,mid,x,y,mu);
    128     if (y >= mid + 1)
    129         mul(k << 1 | 1,mid + 1,r,x,y,mu);
    130     up(k);
    131 }
    132 void chg(int k,int l,int r,int x,int y,int c)
    133 {
    134     down(k,l,r);
    135     if (x <= l && r <= y)
    136     {
    137         sum[1][k] = (r - l + 1) % mo * c % mo;
    138         sum[2][k] = sum[1][k] * c % mo;
    139         sum[3][k] = sum[2][k] * c % mo;
    140         lzy[0][k] = c;
    141         return;
    142     }
    143     int mid = l + r >> 1;
    144     if (x <= mid)
    145         chg(k << 1,l,mid,x,y,c);
    146     if (y >= mid + 1)
    147         chg(k << 1 | 1,mid + 1,r,x,y,c);
    148     up(k);
    149 }
    150  main()
    151 {
    152     while (scanf("%lld%lld",&n,&m) > 0 && n)
    153     { 
    154         for (int i = 1;i <= n;i++)
    155             vec[i] = 0;
    156         build(1,1,n);
    157         int opt,tl,tr,tv;
    158         for (int i = 1;i <= m;i++)
    159         {
    160             scanf("%lld",&opt);
    161             if (opt == 1)
    162             {
    163                 scanf("%lld%lld%lld",&tl,&tr,&tv);
    164                 add(1,1,n,tl,tr,tv % mo);
    165             }else if (opt == 2)
    166             {
    167                 scanf("%lld%lld%lld",&tl,&tr,&tv);
    168                 mul(1,1,n,tl,tr,tv % mo);
    169             }else if (opt == 3)
    170             {
    171                 scanf("%lld%lld%lld",&tl,&tr,&tv);
    172                 chg(1,1,n,tl,tr,tv % mo); 
    173             }else
    174             {
    175                 scanf("%lld%lld%lld",&tl,&tr,&tv);
    176                 printf("%lld
    ",query(1,1,n,tl,tr,tv));
    177             }
    178         }
    179     }
    180     return 0;
    181 }
  • 相关阅读:
    关于asp.net中Repeater控件的一些应用
    Linux查看程序端口占用情况
    php 验证身份证有效性,根据国家标准GB 11643-1999 15位和18位通用
    给Nginx配置一个自签名的SSL证书
    让你提升命令行效率的 Bash 快捷键 [完整版]
    关系数据库常用SQL语句语法大全
    php 跨域 form提交 2种方法
    Vimium~让您的Chrome起飞
    vim tab设置为4个空格
    CENTOS 搭建SVN服务器(附自动部署到远程WEB)
  • 原文地址:https://www.cnblogs.com/iat14/p/12194962.html
Copyright © 2011-2022 走看看