Can you answer these queries? HDU - 4027 线段树区间开方修改(优化)+求和

在这里插入图片描述

在这里插入图片描述
题目是对一个区间内的所有数进行开平方,然后计算该区间内的和。
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值