1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| #include <bits/stdc++.h> using namespace std;
#define endl '\n' #define int long long #define FOR(i, a, b) for(int i = a; i < b; i++)
template<class Info> struct SegmentTree { int n; std::vector<Info> info; SegmentTree() : n(0) {} SegmentTree(int n_, Info v_ = Info()) { init(n_, v_); } template<class T> SegmentTree(std::vector<T> init_) { init(init_); } void init(int n_, Info v_ = Info()) { init(std::vector<Info>(n_, v_)); } template<class T> void init(std::vector<T> init_) { n = init_.size(); info.assign(4 * n + 5, Info()); std::function<void(int, int, int)> build = [&](int p, int l, int r) { if (r - l == 1) { info[p] = {init_[l], init_[l]}; return; } int m = (l + r) / 2; build(2 * p, l, m); build(2 * p + 1, m, r); pull(p); }; build(1, 0, n); } void pull(int p) { info[p] = info[2 * p] + info[2 * p + 1]; }
Info rangeQuery(int p, int l, int r, int x, int y) { if (l >= y || r <= x) { return Info(); } if (l >= x && r <= y) { return info[p]; } int m = (l + r) / 2; return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y); } Info rangeQuery(int l, int r) { return rangeQuery(1, 0, n, l, r); }
void rangeSqrt(int p, int l, int r, int x, int y){ if(l>=y or r<=x) return;
if(info[p].y<=1) return;
if(r-l==1){ info[p].x = sqrt(info[p].x); info[p].y = info[p].x; return; }
int m = (l+r)/2; rangeSqrt(2*p, l, m, x, y); rangeSqrt(2*p+1, m, r, x, y); pull(p); } void rangeSqrt(int l, int r){ rangeSqrt(1, 0, n, l, r); } };
struct Info { int x = 0; int y = 0; };
Info operator+(const Info &a, const Info &b) { return {a.x + b.x, max(a.y, b.y)}; }
void solve() { int n, q; cin >> n >> q;
vector < int > arr(n); FOR(i, 0, n) cin >> arr[i];
SegmentTree < Info > st(arr);
int x, l, r; FOR(i, 0, q){ cin >> x >> l >> r; if(x==0){ cout << st.rangeQuery(l-1, r).x << endl; }else{ st.rangeSqrt(l-1, r); } }
}
signed main() { ios::sync_with_stdio(false),cin.tie(0); int t = 1; while (t--) solve(); return 0; }
|