hdu 4578 Transformation 线段树

Posted iat14

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

以上是关于hdu 4578 Transformation 线段树的主要内容,如果未能解决你的问题,请参考以下文章

30-Transformation(HDU4578)-区间线段树(复杂)

HDU - 4578 Transformation(线段树区间修改)

Transformation HDU - 4578

hdu 4578 Transformation 线段树

HDU - 4578 Transformation

Transformation HDU - 4578 完全平方公式和立方公式展开,有点麻烦