码迷,mamicode.com
首页 > 其他好文 > 详细

Transformation

时间:2017-03-28 00:27:27      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:lan   覆盖   数据   ==   ref   ret   lap   show   log   

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了...算了明天再改吧晚安

 

技术分享
  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 = 0;
 42         tr[o].lazc = 0;    
 43     }
 44     if(tr[o].laza) {
 45         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;
 46         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;
 47         tr[lc].s2 = (tr[lc].s2 + tr[o].laza * tr[lc].s1 * 2 + tr[o].laza * tr[o].laza * (mid - l + 1)) % Mod;
 48         tr[rc].s2 = (tr[rc].s2 + tr[o].laza * tr[rc].s1 * 2 + tr[o].laza * tr[o].laza * (r - mid)) % Mod;
 49         tr[lc].s1 = (tr[lc].s1 + tr[o].laza * (mid - l + 1)) % Mod;
 50         tr[rc].s1 = (tr[rc].s1 + tr[o].laza * (r - mid)) % Mod;
 51         tr[lc].laza = (tr[lc].laza + tr[o].laza) % Mod;
 52         tr[rc].laza = (tr[rc].laza + tr[o].laza) % Mod;
 53         tr[o].laza = 0;
 54     }
 55     if(tr[o].lazm != 1) {
 56         tr[lc].s3 = (tr[lc].s3 * tr[o].lazm * tr[o].lazm * tr[o].lazm) % Mod;
 57         tr[rc].s3 = (tr[rc].s3 * tr[o].lazm * tr[o].lazm * tr[o].lazm) % Mod;
 58         tr[lc].s2 = (tr[lc].s2 * tr[o].lazm * tr[o].lazm) % Mod;
 59         tr[rc].s2 = (tr[rc].s2 * tr[o].lazm * tr[o].lazm) % Mod;
 60         tr[lc].s1 = (tr[lc].s1 * tr[o].lazm) % Mod;
 61         tr[rc].s1 = (tr[rc].s1 * tr[o].lazm) % Mod;
 62         tr[lc].lazm = (tr[lc].lazm * tr[o].lazm) % Mod;
 63         tr[rc].lazm = (tr[rc].lazm * tr[o].lazm) % Mod;
 64         tr[o].lazm = 1;
 65     }
 66 }
 67 
 68 void build(int o, int l, int r) {
 69     tr[o].clear();
 70     if(l == r) return;
 71     int mid = (l + r) >> 1;
 72     build(lc, l, mid);
 73     build(rc, mid + 1, r);
 74 }
 75 
 76 void add(int o, int l, int r) {
 77     if(l != r) pushdown(o, l, r);
 78     if(x <= l && r <= y) {
 79         tr[o].s3 = (tr[o].s3 + z * tr[o].s2 * 3 + z * z * tr[o].s1 * 3 + z * z * z * (r - l + 1)) % Mod;
 80         tr[o].s2 = (tr[o].s2 + z * tr[o].s1 * 2 + z * z * (r - l + 1)) % Mod;
 81         tr[o].s1 = (tr[o].s1 + z * (r - l + 1)) % Mod;
 82         tr[o].laza = (tr[o].laza + z) % Mod;
 83         return;
 84     }
 85     int mid = (l + r) >> 1;
 86     if(x <= mid) add(lc, l, mid);
 87     if(y >  mid) add(rc, mid + 1, r);
 88     pushup(o);
 89 }
 90 
 91 void multiply(int o, int l, int r) {
 92     if(l != r) pushdown(o, l, r);
 93     if(x <= l && r <= y) {
 94         tr[o].s3 = (tr[o].s3 * z * z * z) % Mod;
 95         tr[o].s2 = (tr[o].s2 * z * z) % Mod;
 96         tr[o].s1 = (tr[o].s1 * z) % Mod;
 97         tr[o].lazm = (tr[o].lazm * z) % Mod;
 98         return;
 99     }
100     int mid = (l + r) >> 1;
101     if(x <= mid) multiply(lc, l, mid);
102     if(y >  mid) multiply(rc, mid + 1, r);
103     pushup(o);
104 }
105 
106 void cover(int o, int l, int r) {
107     if(l != r) pushdown(o, l, r);
108     if(x <= l && r <= y) {
109         tr[o].s3 = z * z * z * (r - l + 1)  % Mod;
110         tr[o].s2 = z * z * (r - l + 1) % Mod; 
111         tr[o].s1 = z * (r - l + 1) % Mod; 
112         tr[o].lazc = z;    
113         return;
114     }
115     int mid = (l + r) >> 1;
116     if(x <= mid) cover(lc, l, mid);
117     if(y >  mid) cover(rc, mid + 1, r);
118     pushup(o);
119 }
120 
121 ll ask(int o, int l, int r) {
122     if(l != r) pushdown(o, l, r);
123     if(x <= l && r <= y) {
124         switch(z) {
125             case 1:return tr[o].s1;
126             case 2:return tr[o].s2;
127             case 3:return tr[o].s3;
128         }
129     }
130     ll res = 0;
131     int mid = (l + r) >> 1;
132     if(x <= mid) res += ask(lc, l, mid);
133     if(y >  mid) res += ask(rc, mid + 1, r);
134     return res;
135 }
136 
137 int main() {
138     while(scanf("%d %d", &n, &m), n != 0) {
139         build(1, 1, n);
140         while(m --) {
141             scanf("%d %d %d %lld", &op, &x, &y, &z);
142             switch(op) {
143                 case 1:add(1, 1, n);break;
144                 case 2:multiply(1, 1, n);break;
145                 case 3:cover(1, 1, n);break;
146                 case 4:printf("%lld\n", ask(1, 1, n));break;
147             }
148         }
149     }
150     return 0;
151 }
View Code

 

Transformation

标签:lan   覆盖   数据   ==   ref   ret   lap   show   log   

原文地址:http://www.cnblogs.com/ytytzzz/p/6629360.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!