题目是对一个区间内的所有数进行开平方,然后计算该区间内的和。
WA点:这道题普通更新求和去做会T(QAQ),因为你对一个数重复进行开方运算一直会使这个数字趋近于1,当它变成1时无论做什么操作都可以直接跳出了,大大减少了时间复杂度。
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#define inf 0x3f3f3f3f
#define cha 1e-6
#define ll long long
using namespace std;
const int maxn = 1e5 + 6;
ll node[270000],lazy[270000],maxx[270000];
ll a[100005];
inline void build(int s ,int t,int p ){
lazy[p]=0;
if(s==t){
node[p]=a[s];
maxx[p]=a[s];
return ;
}
int m=(s+t)/2;
build(s,m,p*2), build(m+1,t,p*2+1);
node[p]=node[p*2]+node[(2*p)+1];
maxx[p]=max(maxx[p*2],maxx[(2*p)+1]);
}
inline ll getsum(int l,int r,int s ,int t,int p){
if(l<=s&&t<=r)
return node[p];
ll m=(s+t)/2,sum=0;
if (lazy[p]){
node[p*2] += lazy[p]*(m-s+1), node[(p *2)+1] += lazy[p] * (t - m),
lazy[p *2] += lazy[p], lazy[(p*2)+1] += lazy[p];
lazy[p] = 0;
}
if(l<=m) sum+=getsum(l,r,s,m,p*2);
if(r>m) sum+=getsum(l,r,m+1,t,p*2+1);
return sum;
}
// inline void updateplus(int l, int r, int c, int s, int t, int p) {
// if (l <= s && t <= r) {
// node[p] += (t - s + 1) * c, lazy[p] += c;
// return;
// }
// int m = (s + t)/2;
// if (lazy[p])
// node[p*2] += lazy[p]*(m-s+1), node[(p *2)+1] += lazy[p] * (t - m),
// lazy[p *2] += lazy[p], lazy[(p*2)+1] += lazy[p];
// lazy[p] = 0;
// if (l <= m) updateplus(l, r, c, s, m, p *2);
// if (r > m) updateplus(l, r, c, m + 1, t, (p *2)+1);
// node[p] = node[p*2] + node[p*2+1];
// }
// inline void updatereplace(int l,int r,int c,int s,int t ,int p){
// if(l<=s&&t<=r){
// node[p]=(t-s+1)*c,lazy[p]=c;
// return ;
// }
// int m = (s + t)/2;
// if (lazy[p]){
// node[p*2] = lazy[p]*(m-s+1), node[(p *2)+1] = lazy[p] * (t - m),
// lazy[p *2] = lazy[p], lazy[(p*2)+1] = lazy[p];
// lazy[p] = 0;
// }
// if (l <= m) updatereplace(l, r, c, s, m, p *2);
// if (r > m) updatereplace(l, r, c, m + 1, t, (p *2)+1);
// node[p] = node[p*2] + node[p*2+1];
// }
inline void updategen(int l,int r,int s,int t,int p){
if(maxx[p]<=1) return ;
if(s==t){
node[p]=sqrt(node[p]);
maxx[p]=node[p];
return;
}
int m=(s+t)/2;
if(l<=m) updategen(l,r,s,m,p*2);
if(r>m) updategen(l,r,m+1,t,2*p+1);
node[p] = node[p*2] + node[p*2+1];
maxx[p]=max((int)maxx[p*2],(int)maxx[(2*p)+1]);
}
void swap(int &a, int &b) {
int tem = a;
a = b;
b = tem;
}
int n,t=1,q,code,x,y;
int main()
{
ios::sync_with_stdio(false);
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; i++) {
scanf("%lld", a + i);
}
build(1, n,1 );
scanf("%d", &q);
printf("Case #%d:\n", t++);
for (int i = 1; i <= q; i++) {
scanf("%d%d%d", &code, &x, &y);
if (x > y) swap(x, y);
if (code == 0) {
updategen(x,y,1,n,1);
}
else {
printf("%lld\n", getsum(x,y,1,n,1));
}
}
printf("\n");
}
system("pause");
return 0;
}