D. 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?
Input
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.
Output
For each operation 1, please print a line containing the answer. Notice that the answer may exceed the 32-bit integer.
Examples
input
5 5
1 2 3 4 5
2 3 5 4
3 3 5
1 2 5
2 1 3 3
1 1 3
output
8
5
input
10 10
6 9 6 7 6 1 10 10 9 5
1 3 9
2 7 10 9
2 5 10 8
1 4 7
3 3 7
2 7 9 9
1 2 4
1 6 6
1 5 9
3 1 10
output
49
15
23
1
9
【解题报告】
题目大意是要求维护一棵支持区间取膜,单点更新,区间求和的线段树。
区间取膜看似不好解决,但实际上我们可以发现,每次取膜过后区间内的数至少减半。
所以说在修改操作经过log次之后就不在有效。
直接暴力取膜即可。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ls rt<<1
#define rs rt<<1|1
struct Node
{
ll maxx,sum;
}node[N<<2];
void pushup(int rt)
{
node[rt].maxx=max(node[ls].maxx,node[rs].maxx);
node[rt].sum=node[ls].sum+node[rs].sum;
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%lld",&node[rt].maxx);
node[rt].sum=node[rt].maxx;
return;
}
int m=(l+r)>>1;
build(lson);build(rson);
pushup(rt);
}
void point_update(int index,int k,int l,int r,int rt)
{
if(l==r)
{
node[rt].maxx=k;
node[rt].sum=k;
return;
}
int m=(l+r)>>1;
if(index<=m) point_update(index,k,lson);
else point_update(index,k,rson);
pushup(rt);
}
void interval_update(int L,int R,int mod,int l,int r,int rt)
{
if(L>r||R<l) return;
if(node[rt].maxx<mod) return;
if(l==r)
{
node[rt].sum%=mod;
node[rt].maxx=node[rt].sum;
return;
}
int m=(l+r)>>1;
interval_update(L,R,mod,lson);
interval_update(L,R,mod,rson);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L>r||R<l) return 0;
if(L<=l&&r<=R) return node[rt].sum;
ll sum=0;
int m=(l+r)>>1;
sum+=query(L,R,lson);
sum+=query(L,R,rson);
return sum;
}
int n,m;
int main()
{
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--)
{
int opt,l,r,mod;
scanf("%d",&opt);
if(opt==3)
{
scanf("%d%d",&l,&r);
point_update(l,r,1,n,1);
}
if(opt==2)
{
scanf("%d%d%d",&l,&r,&mod);
interval_update(l,r,mod,1,n,1);
}
if(opt==1)
{
scanf("%d%d",&l,&r);
printf("%lld\n",query(l,r,1,n,1));
}
}
return 0;
}