BZOJ#3038上帝造题的七分钟2
上帝造题的七分钟2
思路:
数据范围\(10^{12}\),大概开方5六次之后就变成1,当一个区间全是1的时候就没必要改变,其他暴力修改即可
代码:
#include <bits/stdc++.h>
#define int long long
int _ = 0, Case = 1;
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
const int N = 100010;
int a[N];
struct T {
int l, r, val, tag;
} tr[N << 2];
void pushup(int p) {
tr[p].val = tr[p << 1].val + tr[p << 1 | 1].val;
tr[p].tag = tr[p << 1].tag + tr[p << 1 | 1].tag;
}
void build(int p, int l, int r) {
if (l == r) {
tr[p] = {l, r, a[l], 0};
return;
}
tr[p] = {l, r, 0, 0};
int mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
pushup(p);
}
int query(int p, int l, int r) {
if (tr[p].l >= l and tr[p].r <= r) return tr[p].val;
int mid = tr[p].l + tr[p].r >> 1;
if (l > mid) return query(p << 1 | 1, l, r);
else if (r <= mid) return query(p << 1, l, r);
return query(p << 1, l, r) + query(p << 1 | 1, l, r);
}
void modify(int p, int l, int r) {
if (tr[p].tag == tr[p].r - tr[p].l + 1) {
return;
}
else {
if (tr[p].l == tr[p].r) {
if (tr[p].val <= 1) {
tr[p].tag = 1;
} else {
tr[p].tag = 0;
}
tr[p].val = sqrt(tr[p].val);
if (tr[p].val <= 1) tr[p].tag = 1;
else tr[p].tag = 0;
return;
} else {
int mid = tr[p].l + tr[p].r >> 1;
if (l <= mid) modify(p<<1, l, r);
if (r > mid) modify(p<<1|1, l, r);
pushup(p);
}
}
}
void solve(int Case) {
int n, m;
cin >> n ;
for (int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
cin >> m;
for (; m--;) {
int k, l, r;
cin >> k >> l >> r;
if (!k) modify(1, min(l, r), max(l, r));
else cout << query(1, min(l, r), max(l, r)) << nline;
}
}
signed main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
// cin >> _; for (Case = 1; Case <= _; Case++)
solve(Case);
return 0;
}