#include<bits/stdc++.h>
#define int long long
#define mem(x) memset(x,0,sizeof(x))
using namespace std;
int read(){
int s = 0,w = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
while(ch >= '0' && ch <= '9')s = s * 10 + ch - '0',ch = getchar();
return s * w;
}
int n;
int a[1000010];
int l[1000010],r[1000010];
int block;
int num[1000010];
int lazy[1000010];
int len;
int times[1000010];
int sum[1000010];
void update(int x,int y){
int posl = num[x];
int posr = num[y];
if(posl == posr){
for(int i = x;i <= y;i ++){
int vx = sqrt(a[i]);
a[i] = vx;
sum[num[posl]] -= (a[i] - vx);
}
return ;
}
for(int i = x;i <= r[posl];i ++){
int vx = sqrt(a[i]);
a[i] = vx;
sum[num[posl]] -= (a[i] - vx);
}
for(int i = num[x] + 1;i <= num[y] - 1;i ++)lazy[i] ++;
for(int i = l[posr];i <= y;i ++){
int vx = sqrt(a[i]);
a[i] = vx;
sum[num[posl]] -= (a[i] - vx);
}
return ;
}
int query(int x,int y){
int posl = num[x];
int posr = num[y];
int ans = 0;
if(posl == posr){
for(int i = x;i <= y;i ++){
if(a[i] == 0)continue;
if(lazy[posl] >= 5){
ans ++;
continue;
}
int s = a[i];
for(int j = 1;j <= lazy[posl];j ++){
s = sqrt(s);
}
ans += s;
}
return ans;
}
for(int i = x;i <= r[posl];i ++){
if(a[i] == 0)continue;
if(lazy[num[i]] >= 5){
ans ++;
continue;
}
int s = a[i];
for(int j = 1;j <= lazy[num[i]];j ++){
s = sqrt(s);
}
ans += s;
}
for(int i = num[x] + 1;i <= num[y] - 1;i ++){
if(lazy[i] >= 5)ans += block - times[i];
else {
int s = a[i];
for(int j = 1;j <= lazy[i];j ++){
s = sqrt(s);
}
ans += s;
}
}
for(int i = l[posr];i <= y;i ++){
if(a[i] == 0)continue;
if(lazy[num[i]] >= 5){
ans ++;
continue;
}
int s = a[i];
for(int j = 1;j <= lazy[num[i]];j ++){
s = sqrt(s);
}
ans += s;
}
return ans;
}
signed main(){
cin>>n;
block = sqrt(n);
len = ceil(n * 1.0 / block);
for(int i = 1;i <= len;i ++){
l[i] = (i - 1) * block + 1;
r[i] = i * block;
}
for(int i = 1;i <= n;i ++){
a[i] = read();
num[i] = (i - 1) / block + 1;
sum[num[i]] += a[i];
if(a[i] == 0)times[num[i]] ++;
}
r[len] = n;
for(int i = 1;i <= n;i ++){
int op;
int x,y,w;
op = read(),x = read(),y = read(),w = read();
if(op == 0){
update(x,y);
}
else {
printf("%lld\n",query(x,y));
}
}
return 0;
}
虽然不吃电脑了,但是看看代码还是可以的
具体操作就是区间根号,区间求和