其实这是一道sb题……
哦不其实是两道2333333(还有3038也是同一题)
然而在写3038的时候由于数据太水直接就A掉了。。。
刚刚拿之前的code交上去就WA啦。。。
不能判断区间和是否==r-l+1因为会出现0……所以要开多一个东西表示这个区间还有多少个数不会再改变了
每个数可以开方的次数是很小的,就当做是常数非常小的
O(logn)
吧
这样复杂度就是
O(nlog2n)
#include <bits/stdc++.h>
#define lc (u << 1)
#define rc (u << 1 | 1)
#define T int u = 1 , int l = 1 , int r = n
#define L lc , l , m
#define R rc , m + 1 , r
#define rep(i,a,b) for(int i = a;i <= b;i ++)
#define maxn 100007
typedef long long ll;
ll rd() {
char c = getchar();
while (!isdigit(c)) c = getchar( ) ; ll x = c - '0';
while (isdigit(c = getchar())) x = x * 10 + c - '0';
return x;
}
ll sum[maxn * 4 + 1] , cnt[maxn * 4 + 1] , a[maxn];
ll n , m , ql , qr;
void build(T) {
if (l == r)
{ sum[u] = a[l] , cnt[u] = (a[l] <= 1) ; return ; }
int m = (l + r) >> 1;
build(L) , build(R);
sum[u] = sum[lc] + sum[rc];
cnt[u] = cnt[lc] + cnt[rc];
}
void modi(T) {
if (cnt[u] == r - l + 1)
return ;
if (l == r)
{ sum[u] = (ll)sqrt(sum[u]) , cnt[u] = (sum[u] <= 1) ; return ; }
int m = (l + r) >> 1;
if (ql <= m) modi(L);
if (qr > m) modi(R);
sum[u] = sum[lc] + sum[rc];
cnt[u] = cnt[lc] + cnt[rc];
}
ll que(T) {
if (ql <= l && r <= qr)
return sum[u];
int m = (l + r) >> 1;
ll ret = 0;
if (ql <= m) ret += que(L);
if (qr > m) ret += que(R);
return ret;
}
void input() {
n = rd();
rep(i , 1 , n) a[i] = rd();
build();
}
void solve() {
m = rd();
rep(i , 1 , m) {
int k = rd();
ql = rd() , qr = rd();
if (ql > qr) std::swap(ql , qr);
if (k == 1) printf("%lld\n" , que());
else modi();
}
}
int main() {
input();
solve();
return 0;
}