题目链接
题意:
三种操作:
1 l r:
1
l
r
:
求
∑ri=lai
∑
i
=
l
r
a
i
2 l r x:
2
l
r
x
:
对所有
i∈[l,r]
i
∈
[
l
,
r
]
,
ai=aimodx
a
i
=
a
i
mod
x
3 k x:
3
k
x
:
ak=x
a
k
=
x
思路:
神一般的复杂度分析。。。。记录区间最大值,如果
x
x
比区间最大值还大,显然不更新,否则暴力更新。因为如果是的话,如果
x>y2
x
>
y
2
,那么
y
y
取模之后小于,如果
x<y2
x
<
y
2
,取模之后也
y2
y
2
,故每个数取模不会超过
logn
log
n
次。。。
#include<bits/stdc++.h>
typedef long long ll;
const int maxn = 1e5 + 10;
using namespace std;
ll sum[maxn * 4], val[maxn * 4];
void build(int o, int l, int r) {
if(l == r) { cin >> sum[o]; val[o] = sum[o]; return ; }
int mid = (l + r) >> 1;
build(o << 1, l, mid);
build(o << 1 | 1, mid + 1, r);
val[o] = max(val[o << 1], val[o << 1 | 1]);
sum[o] = sum[o << 1] + sum[o << 1 | 1];
}
void update_set(int o, int l, int r, int ind, int x) {
if(l == r) { val[o] = sum[o] = x; return ; }
int mid = (l + r) >> 1;
if(ind <= mid) update_set(o << 1, l, mid, ind, x);
else update_set(o << 1 | 1, mid + 1, r, ind, x);
sum[o] = sum[o << 1] + sum[o << 1 | 1];
val[o] = max(val[o << 1], val[o << 1 | 1]);
}
void update_mod(int o, int l, int r, int ql, int qr, int mod) {
if(l > qr || r < ql) return ;
if(l >= ql && r <= qr && val[o] < mod) return ;
if(l == r) { sum[o] %= mod; val[o] = sum[o]; return ; }
int mid = (l + r) >> 1;
int o1 = o << 1, o2 = o1 | 1;
update_mod(o1, l, mid, ql, qr, mod);
update_mod(o2, mid + 1, r, ql, qr, mod);
sum[o] = sum[o1] + sum[o2];
val[o] = max(val[o1], val[o2]);
}
ll query(int o, int l, int r, int ql, int qr) {
if(l > qr || r < ql) return 0;
if(l >= ql && r <= qr) return sum[o];
int mid = (l + r) >> 1, o1 = o << 1, o2 = o1 | 1;
ll p1 = query(o1, l, mid, ql, qr);
ll p2 = query(o2, mid + 1, r, ql, qr);
return p1 + p2;
}
int main() {
ios::sync_with_stdio(0);
int n, m, T, kase = 1;
cin >> n >> m;
build(1, 1, n);
while(m--) {
int op, l, r, x;
cin >> op;
if(op == 1) {
cin >> l >> r;
cout << query(1, 1, n, l, r) << endl;
} else if(op == 2) {
cin >> l >> r >> x;
update_mod(1, 1, n, l, r, x);
} else {
cin >> l >> x;
update_set(1, 1, n, l, x);
}
}
return 0;
}