Codeforces D. The Child and Sequence (线段树)

D. The Child and Sequence

time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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:

  1. Print operation l, r. Picks should write down the value of .
  2. Modulo operation l, r, x. Picks should perform assignment a[i] = a[imod x for each i (l ≤ i ≤ r).
  3. 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

Copy

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

Copy

8
5

input

Copy

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

Copy

49
15
23
1
9

Note

Consider the first testcase:

  • At first, a = {1, 2, 3, 4, 5}.
  • After operation 1, a = {1, 2, 3, 0, 1}.
  • After operation 2, a = {1, 2, 5, 0, 1}.
  • At operation 3, 2 + 5 + 0 + 1 = 8.
  • After operation 4, a = {1, 2, 2, 0, 1}.
  • At operation 5, 1 + 2 + 2 = 5.

题目大意: 有三种操作:

  1. Print operation l, r. Picks should write down the value of .
  2. Modulo operation l, r, x. Picks should perform assignment a[i] = a[imod x for each i (l ≤ i ≤ r).
  3. Set operation k, x. Picks should set the value of a[k] to x (in other words perform an assignment a[k] = x).

解题思路:线段树维护区间和,区间最大值,在对于第二中操作时,可以剪纸,就是说在x大于区间最大值的时候,可以不进行取模操作,因为取模和没取模是一样的效果。这样做可以减少时间的复杂度。

题目链接:https://codeforces.com/problemset/problem/438/D

/*
@Author: Top_Spirit
@Language: C++
*/
#include <bits/stdc++.h>
using namespace std ;
typedef unsigned long long ull ;
typedef long long ll ;
typedef pair < ll, ll > P ;
const ll Maxn = 1e5 + 100 ;
const int Mod = 1e9 + 7  ;
const int INF = 0x3f3f3f3f ;

#define lson ri << 1, l, Mid
#define rson ri << 1 | 1, Mid + 1, r

ll Max[Maxn << 2], sum[Maxn << 2] ;
ll n, m ;

void pushUp (ll ri){
    sum[ri] = sum[ri << 1 ] + sum[ri << 1 | 1] ;
    Max[ri] = max(Max[ri << 1 ], Max[ri << 1 | 1]) ;
}

void Build (ll ri, ll l, ll r){
    if (l == r) {
        cin >> sum[ri] ;
        Max[ri] = sum[ri] ;
        return ;
    }
    ll Mid = (l + r) >> 1 ;
    Build(lson) ;
    Build(rson) ;
    pushUp(ri) ;
}

ll query (ll L, ll R, ll ri, ll l, ll r){
    if (l >= L && r <= R) return sum[ri] ;
    ll Mid = (l + r) >> 1 ;
    ll ans = 0 ;
    if (L <= Mid) ans += query(L, R, lson) ;
    if (R > Mid) ans += query(L, R, rson) ;
    return ans ;
}

void Updata1(ll L, ll R, ll x, ll ri, ll l, ll r){
    if (x > Max[ri]) return ;
    if (l == r){
        sum[ri] %= x ;
        Max[ri] %= x ;
        return ;
    }
    ll Mid = (l + r) >> 1 ;
    if (L <= Mid) Updata1(L, R, x, lson) ;
    if (R > Mid) Updata1(L, R, x, rson) ;
    pushUp(ri) ;
}

void Updata2(ll k, ll x, ll ri, ll l, ll r){
    if (l == r) {
        sum[ri] = x ;
        Max[ri] = x ;
        return ;
    }
    ll Mid = (l + r) >> 1 ;
    if (k <= Mid) Updata2(k, x, lson) ;
    if (k > Mid) Updata2(k, x, rson) ;
    pushUp(ri) ;
}

int main (){
    cin >> n >> m ;
    Build(1, 1, n) ;
    while (m--){
        int op ;
        cin >> op ;
        if (op == 1) {
            ll l, r ;
            cin >> l >> r ;
            ll ans = query(l, r, 1, 1, n) ;
            cout << ans << endl ;
        }
        else if (op == 2){
            ll l, r, x ;
            cin >> l >> r >> x ;
            Updata1(l, r, x , 1, 1, n) ;
        }
        else {
            ll k, x ;
            cin >> k >> x ;
            Updata2(k, x, 1, 1, n) ;
        }
    }
    return 0 ;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值