花神游历各国
Description
Input
Output
每次x=1时,每行一个整数,表示这次旅行的开心度
Sample Input
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
Sample Output
101
11
11
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9
Solution
一个数最多只能开方loglog次,所以暴力开方,统计该区间是否还需要修改。
Code
#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define MS(_) memset(_, 0, sizeof(_))
#define PB push_back
#define MP make_pair
#define debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long ll;
typedef pair<int, int> PII;
template<typename T> inline void read(T &x){
x = 0; T f = 1; char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
x *= f;
}
const int N = 100000+100;
struct Node{
int l, r, need; ll sum;
Node *lc, *rc;
inline void push_up(){
sum = lc->sum + rc->sum;
need = lc->need | rc->need;
}
}pool[N<<2], *tail = pool, *root = pool;
int n, m;
ll a[N];
inline void build(Node *(&rt), int l, int r){
rt = tail++; rt->l = l; rt->r = r;
if (l == r) { rt->sum = a[l]; rt->need = (a[l]!=0 && a[l]!=1); return; }
int mid = l+r >> 1;
build(rt->lc, l, mid);
build(rt->rc, mid+1, r);
rt->push_up();
}
inline void modify(Node *rt, int l, int r){
if (!rt->need) return;
if (rt->l == rt->r) {
rt->sum = (int)sqrt(rt->sum);
if (rt->sum <= 1) rt->need = 0;
return;
}
int mid = rt->l+rt->r >> 1;
if (l <= mid) modify(rt->lc, l, r);
if (r > mid) modify(rt->rc, l, r);
rt->push_up();
}
inline ll query(Node *rt, int l, int r){ ll res = 0;
if (l <= rt->l && rt->r <= r) return rt->sum;
int mid = rt->l+rt->r >> 1;
if (l <= mid) res += query(rt->lc, l, r);
if (r > mid) res += query(rt->rc, l, r);
return res;
}
int main(){
read(n);
rep(i, 1, n) read(a[i]);
build(root, 1, n);
read(m);
while (m--){ int k, l, r;
read(k); read(l); read(r); if (l > r) swap(l, r);
if (k == 2) modify(root, l, r);
else printf("%lld\n", query(root, l, r));
}
return 0;
}