P4145 上帝造题的七分钟2 / 花神游历各国
最多开几次根就变成1了 这里我们选择 维护区间 和 如果区间和等于区间长度 不更新
不等于 更新到底 反正最多跟新不了几次
正好问的也是区间和。。
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 100050;
ll n, k;
ll tree[maxn << 2];
void pushup(int rt) {
tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}
void build(int l, int r, int rt) {
if(l == r) {
scanf("%lld", &tree[rt]);
return ;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
pushup(rt);
}
void update(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R && tree[rt] == (ll)(r - l + 1)) return;
if(l == r) {
tree[rt] = sqrt(1.0 * tree[rt]);
return;
}
int m = (l + r) >> 1;
if(L <= m)
update(L, R, l, m, rt << 1);
if(R > m)
update(L, R, m + 1, r, rt << 1 | 1);
pushup(rt);
}
ll query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) return tree[rt];
int m = (l + r) >> 1;
ll res = 0;
if(L <= m)
res += query(L, R, l, m, rt << 1);
if(R > m)
res += query(L, R, m + 1, r, rt << 1 | 1);
return res;
}
int main() {
cin >> n;
build(1, n, 1);
cin >> k;
for(int i = 0; i < k; i++) {
int cmd, l, r;
cin >> cmd >> l >> r;
if(r < l) swap(r, l);
if(cmd == 0) update(l, r, 1, n, 1);
if(cmd == 1) printf("%lld\n", query(l, r, 1, n, 1));
}
return 0;
}
区间取模
CF - 438D
https://codeforces.com/problemset/problem/438/D
和上面一样 其实也就是看最大值 取模 只要能取 就一定让 当前数据 减低一半
所以接着暴力更
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 100050;
ll n, k;
ll tree[maxn << 2], mas[maxn << 2];
void pushup(int rt) {
tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
mas[rt] = max(mas[rt << 1], mas[rt << 1 | 1]);
}
void build(int l, int r, int rt) {
if(l == r) {
scanf("%lld", &tree[rt]);
mas[rt] = tree[rt];
return ;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
pushup(rt);
}
void update(int L, int R, int l, int r, int rt, int p) {
if(L <= l && r <= R && mas[rt] < p) return;
if(l == r) {
tree[rt] = tree[rt] % p;
mas[rt] = tree[rt];
return;
}
int m = (l + r) >> 1;
if(L <= m) update(L, R, l, m, rt << 1, p);
if(R > m) update(L, R, m + 1, r, rt << 1 | 1, p);
pushup(rt);
}
void upd(int L, int l, int r, int rt, int val) {
if(l == r) {
tree[rt] = val;
mas[rt] = val;
return;
}
int m = (l + r) >> 1;
if(L <= m) upd(L, l, m, rt << 1, val);
else upd(L, m + 1, r, rt << 1 | 1, val);
pushup(rt);
}
ll query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) return tree[rt];
int m = (l + r) >> 1;
ll res = 0;
if(L <= m) res += query(L, R, l, m, rt << 1);
if(R > m) res += query(L, R, m + 1, r, rt << 1 | 1);
return res;
}
int main() {
cin >> n >> k;
build(1, n, 1);
for(int i = 0; i < k; i++) {
int cmd, l, r, p;
cin >> cmd >> l >> r;
if(cmd == 3) upd(l, 1, n, 1, r);
if(cmd == 2) cin >> p, update(l, r, 1, n, 1, p);
if(cmd == 1) printf("%lld\n", query(l, r, 1, n, 1));
}
return 0;
}