HDU 4578 Transformation (线段树)

Transformation

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)
Total Submission(s): 49    Accepted Submission(s): 16

Problem Description Yuanfang is puzzled with the question below: 

There are n integers, a
1, a
2, …, a
n. The initial values of them are 0. There are four kinds of operations.

Operation 1: Add c to each number between a
x and a
y inclusive. In other words, do transformation a
k<—a
k+c, k = x,x+1,…,y.

Operation 2: Multiply c to each number between a
x and a
y inclusive. In other words, do transformation a
k<—a
k×c, k = x,x+1,…,y.

Operation 3: Change the numbers between a
x and a
y to c, inclusive. In other words, do transformation a
k<—c, k = x,x+1,…,y.

Operation 4: Get the sum of p power among the numbers between a
x and a
y inclusive. In other words, get the result of a
x
p+a
x+1
p+…+a
y 
p.

Yuanfang has no idea of how to do it. So he wants to ask you to help him.   

 

Input There are no more than 10 test cases.

For each case, the first line contains two numbers n and m, meaning that there are n integers and m operations. 1 <= n, m <= 100,000.

Each the following m lines contains an operation. Operation 1 to 3 is in this format: “1 x y c” or “2 x y c” or “3 x y c”. Operation 4 is in this format: “4 x y p”. (1 <= x <= y <= n, 1 <= c <= 10,000, 1 <= p <= 3)

The input ends with 0 0.  

 

Output For each operation 4, output a single integer in one line representing the result. The answer may be quite large. You just need to calculate the remainder of the answer when divided by 10007.  

 

Sample Input 5 5 3 3 5 7 1 2 4 4 4 1 5 2 2 2 5 8 4 3 5 3 0 0  

 

Sample Output 307 7489  

 

Source
2013ACM-ICPC杭州赛区全国邀请赛  

 

 

很裸的线段树的题目。

 

但是做起来比较麻烦。

 

我用sum1,sum2,sum3分别代表和、平方和、立方和。

 

懒惰标记使用三个变量:

lazy1:是加的数

lazy2:是乘的倍数

lazy3:是赋值为一个常数,为0表示没有。

 

更新操作需要注意很多细节。

 

 

  1 /* **********************************************
  2 Author      : kuangbin
  3 Created Time: 2013/8/10 13:24:03
  4 File Name   : F:\2013ACM练习\比赛练习\2013杭州邀请赛重现\1003.cpp
  5 *********************************************** */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 using namespace std;
 19 const int MOD = 10007;
 20 const int MAXN = 100010;
 21 struct Node
 22 {
 23     int l,r;
 24     int sum1,sum2,sum3;
 25     int lazy1,lazy2,lazy3;
 26 }segTree[MAXN*3];
 27 void build(int i,int l,int r)
 28 {
 29     segTree[i].l = l;
 30     segTree[i].r = r;
 31     segTree[i].sum1 = segTree[i].sum2 = segTree[i].sum3 = 0;
 32     segTree[i].lazy1 = segTree[i].lazy3 = 0;
 33     segTree[i].lazy2 = 1;
 34     int mid = (l+r)/2;
 35     if(l == r)return;
 36     build(i<<1,l,mid);
 37     build((i<<1)|1,mid+1,r);
 38 }
 39 void push_up(int i)
 40 {
 41     if(segTree[i].l == segTree[i].r)
 42         return;
 43     segTree[i].sum1 = (segTree[i<<1].sum1 + segTree[(i<<1)|1].sum1)%MOD;
 44     segTree[i].sum2 = (segTree[i<<1].sum2 + segTree[(i<<1)|1].sum2)%MOD;
 45     segTree[i].sum3 = (segTree[i<<1].sum3 + segTree[(i<<1)|1].sum3)%MOD;
 46 
 47 }
 48 
 49 void push_down(int i)
 50 {
 51     if(segTree[i].l == segTree[i].r) return;
 52     if(segTree[i].lazy3 != 0)
 53     {
 54         segTree[i<<1].lazy3 = segTree[(i<<1)|1].lazy3 = segTree[i].lazy3;
 55         segTree[i<<1].lazy1 = segTree[(i<<1)|1].lazy1 = 0;
 56         segTree[i<<1].lazy2 = segTree[(i<<1)|1].lazy2 = 1;
 57         segTree[i<<1].sum1 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD;
 58         segTree[i<<1].sum2 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD;
 59         segTree[i<<1].sum3 = (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD*segTree[i<<1].lazy3%MOD;
 60         segTree[(i<<1)|1].sum1 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD;
 61         segTree[(i<<1)|1].sum2 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD;
 62         segTree[(i<<1)|1].sum3 = (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD*segTree[(i<<1)|1].lazy3%MOD;
 63         segTree[i].lazy3 = 0;
 64     }
 65     if(segTree[i].lazy1 != 0 || segTree[i].lazy2 != 1)
 66     {
 67         segTree[i<<1].lazy1 = ( segTree[i].lazy2*segTree[i<<1].lazy1%MOD + segTree[i].lazy1 )%MOD;
 68         segTree[i<<1].lazy2 = segTree[i<<1].lazy2*segTree[i].lazy2%MOD;
 69         int sum1,sum2,sum3;
 70         sum1 = (segTree[i<<1].sum1*segTree[i].lazy2%MOD + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD)%MOD;
 71         sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i<<1].sum2 % MOD + 2*segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[i<<1].sum1%MOD + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
 72         sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i<<1].sum3 % MOD;
 73         sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i<<1].sum2) % MOD;
 74         sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i<<1].sum1) % MOD;
 75         sum3 = (sum3 + (segTree[i<<1].r - segTree[i<<1].l + 1)*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
 76         segTree[i<<1].sum1 = sum1;
 77         segTree[i<<1].sum2 = sum2;
 78         segTree[i<<1].sum3 = sum3;
 79         segTree[(i<<1)|1].lazy1 = ( segTree[i].lazy2*segTree[(i<<1)|1].lazy1%MOD + segTree[i].lazy1 )%MOD;
 80         segTree[(i<<1)|1].lazy2 = segTree[(i<<1)|1].lazy2 * segTree[i].lazy2 % MOD;
 81         sum1 = (segTree[(i<<1)|1].sum1*segTree[i].lazy2%MOD + (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[i].lazy1%MOD)%MOD;
 82         sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[(i<<1)|1].sum2 % MOD + 2*segTree[i].lazy1*segTree[i].lazy2%MOD * segTree[(i<<1)|1].sum1%MOD + (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[i].lazy1%MOD*segTree[i].lazy1%MOD)%MOD;
 83         sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[(i<<1)|1].sum3 % MOD;
 84         sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[(i<<1)|1].sum2) % MOD;
 85         sum3 = (sum3 + 3*segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[(i<<1)|1].sum1) % MOD;
 86         sum3 = (sum3 + (segTree[(i<<1)|1].r - segTree[(i<<1)|1].l + 1)*segTree[i].lazy1%MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;
 87         segTree[(i<<1)|1].sum1 = sum1;
 88         segTree[(i<<1)|1].sum2 = sum2;
 89         segTree[(i<<1)|1].sum3 = sum3;
 90         segTree[i].lazy1 = 0;
 91         segTree[i].lazy2 = 1;
 92 
 93     }
 94 }
 95 void update(int i,int l,int r,int type,int c)
 96 {
 97     if(segTree[i].l == l && segTree[i].r == r)
 98     {
 99         c %= MOD;
100         if(type == 1)
101         {
102             segTree[i].lazy1 += c;
103             segTree[i].lazy1 %= MOD;
104             segTree[i].sum3 = (segTree[i].sum3 + 3*segTree[i].sum2%MOD*c%MOD + 3*segTree[i].sum1%MOD*c%MOD*c%MOD + (segTree[i].r - segTree[i].l + 1)*c%MOD*c%MOD*c%MOD)%MOD;
105             segTree[i].sum2 = (segTree[i].sum2 + 2*segTree[i].sum1%MOD*c%MOD + (segTree[i].r - segTree[i].l + 1)*c%MOD*c%MOD)%MOD;
106             segTree[i].sum1 = (segTree[i].sum1 + (segTree[i].r - segTree[i].l + 1)*c%MOD)%MOD;
107         }
108         else if(type == 2)
109         {
110             segTree[i].lazy1 = segTree[i].lazy1*c%MOD;
111             segTree[i].lazy2 = segTree[i].lazy2*c%MOD;
112             segTree[i].sum1 = segTree[i].sum1*c%MOD;
113             segTree[i].sum2 = segTree[i].sum2*c%MOD*c%MOD;
114             segTree[i].sum3 = segTree[i].sum3*c%MOD*c%MOD*c%MOD;
115         }
116         else
117         {
118             segTree[i].lazy1 = 0;
119             segTree[i].lazy2 = 1;
120             segTree[i].lazy3 = c%MOD;
121             segTree[i].sum1 = c*(segTree[i].r - segTree[i].l + 1)%MOD;
122             segTree[i].sum2 = c*(segTree[i].r - segTree[i].l + 1)%MOD*c%MOD;
123             segTree[i].sum3 = c*(segTree[i].r - segTree[i].l + 1)%MOD*c%MOD*c%MOD;
124         }
125         return;
126     }
127     push_down(i);
128     int mid = (segTree[i].l + segTree[i].r)/2;
129     if(r <= mid)update(i<<1,l,r,type,c);
130     else if(l > mid)update((i<<1)|1,l,r,type,c);
131     else
132     {
133         update(i<<1,l,mid,type,c);
134         update((i<<1)|1,mid+1,r,type,c);
135     }
136     push_up(i);
137 }
138 int query(int i,int l,int r,int p)
139 {
140     if(segTree[i].l == l && segTree[i].r == r)
141     {
142         if(p == 1)return segTree[i].sum1;
143         else if(p== 2)return segTree[i].sum2;
144         else return segTree[i].sum3;
145     }
146     push_down(i);
147     int mid = (segTree[i].l + segTree[i].r )/2;
148     if(r <= mid)return query(i<<1,l,r,p);
149     else if(l > mid)return query((i<<1)|1,l,r,p);
150     else return (query(i<<1,l,mid,p)+query((i<<1)|1,mid+1,r,p))%MOD;
151 }
152 
153 int main()
154 {
155     //freopen("in.txt","r",stdin);
156     //freopen("out.txt","w",stdout);
157     int n,m;
158     while(scanf("%d%d",&n,&m) == 2)
159     {
160         if(n == 0 && m == 0)break;
161         build(1,1,n);
162         int type,x,y,c;
163         while(m--)
164         {
165             scanf("%d%d%d%d",&type,&x,&y,&c);
166             if(type == 4)printf("%d\n",query(1,x,y,c));
167             else update(1,x,y,type,c);
168         }
169     }
170     return 0;
171 }

 

 

 

 

 

 

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3250375.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞