438D - The Child and Sequence
At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks.
Fortunately, Picks remembers how to repair the sequence. Initially he should create an integer array a[1], a[2], ..., a[n]. Then he should perform a sequence of m operations. An operation can be one of the following:
- Print operation l, r. Picks should write down the value of .
- Modulo operation l, r, x. Picks should perform assignment a[i] = a[i] mod x for each i (l ≤ i ≤ r).
- Set operation k, x. Picks should set the value of a[k] to x (in other words perform an assignment a[k] = x).
Can you help Picks to perform the whole sequence of operations?
The first line of input contains two integer: n, m (1 ≤ n, m ≤ 105). The second line contains n integers, separated by space:a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ 109) — initial value of array elements.
Each of the next m lines begins with a number type .
- If type = 1, there will be two integers more in the line: l, r (1 ≤ l ≤ r ≤ n), which correspond the operation 1.
- If type = 2, there will be three integers more in the line: l, r, x (1 ≤ l ≤ r ≤ n; 1 ≤ x ≤ 109), which correspond the operation 2.
- If type = 3, there will be two integers more in the line: k, x (1 ≤ k ≤ n; 1 ≤ x ≤ 109), which correspond the operation 3.
For each operation 1, please print a line containing the answer. Notice that the answer may exceed the 32-bit integer.
这题关键是证明啊。 好线段树。
详细证明见:http://codeforces.com/blog/entry/12513
using namespace std;
const int MAX = 1e5+10;
typedef long long LL;
LL sum[MAX<<2],Max[MAX<<2];
void push_up(int o) {
sum[o]=sum[o<<1]+sum[o<<1|1];
Max[o]=max(Max[o<<1],Max[o<<1|1]);
}
void build(int L,int R,int o) {
if(L==R) {
scanf("%I64d",&Max[o]);
sum[o]=Max[o]; return ;
}
int mid=(L+R)>>1;
build(L,mid,o<<1);
build(mid+1,R,o<<1|1);
push_up(o);
}
void modify1(int L,int R,int o,int ls,int rs,int mod) {
if(L==R) {
sum[o]=Max[o]=sum[o]%mod; return;
}
if(Max[o]<mod) return ;
int mid=(L+R)>>1;
if(ls<=mid) modify1(L,mid,o<<1,ls,rs,mod);
if(rs>mid) modify1(mid+1,R,o<<1|1,ls,rs,mod);
push_up(o);
}
void modify2(int L,int R,int o,int k,int x) {
if(L==R) {
sum[o]=Max[o]=x; return ;
}
int mid=(L+R)>>1;
if(k<=mid) modify2(L,mid,o<<1,k,x);
else modify2(mid+1,R,o<<1|1,k,x);
push_up(o);
}
LL Query(int L,int R,int o,int ls,int rs) {
if(ls<=L&&rs>=R) {
return sum[o];
}
LL res=0;
int mid=(L+R)>>1;
if(ls<=mid) res+=Query(L,mid,o<<1,ls,rs);
if(rs>mid) res+=Query(mid+1,R,o<<1|1,ls,rs);
return res;
}
int main() {
int n,m; int t,l,r,k,x;
while(scanf("%d %d",&n,&m)==2) {
build(1,n,1);
for(int i=0;i<m;i++) {
scanf("%d",&t);
if(t==1) {
scanf("%d %d",&l,&r) ;
printf("%I64d\n",Query(1,n,1,l,r));
}
else if(t==2) {
scanf("%d %d %d",&l,&r,&x);
modify1(1,n,1,l,r,x) ;
}
else {
scanf("%d %d",&k,&x);
modify2(1,n,1,k,x);
}
}
}
return 0;
}