HDU4027 Can you answer these queries?

有两种操作,一是给区间内所有的数开根号,二是区间求和。

线段树单点更新,区间求和的模板~

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1e6+14;
struct node {
    int l;
    int r;
    long long sum;
}segTree[maxn*4];
long long a[maxn];
void build (int i,int l,int r) {
    segTree[i].l=l;
    segTree[i].r=r;
    if (l==r) {
        segTree[i].sum=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum;
}
void update (int i,int a,int b) {
    if (segTree[i].l==a&&segTree[i].r==b&&segTree[i].sum==b-a+1) return;
    if (segTree[i].l==segTree[i].r) {
        segTree[i].sum=sqrt(segTree[i].sum);
        return;
    }
    int mid=(segTree[i].l+segTree[i].r)>>1;
    if (b<=mid) update(i<<1,a,b);
    else if (a>mid) update(i<<1|1,a,b);
    else {
        update(i<<1,a,mid);
        update(i<<1|1,mid+1,b);
    }
    segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum;
}
long long query (int i,int l,int r) {
    if (segTree[i].l==l&&segTree[i].r==r) return segTree[i].sum;
    int mid=(segTree[i].l+segTree[i].r)>>1;
    if (r<=mid) return query(i<<1,l,r);
    else if (l>mid) return query(i<<1|1,l,r);
    else return query(i<<1,l,mid)+query(i<<1|1,mid+1,r);
}
int main () {
    int n,m,l,r,flag,cnt=0;
    while (~scanf("%d",&n)) {
        cnt++;
        for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
        build (1,1,n);
        scanf ("%d",&m);
        printf ("Case #%d:
",cnt);
        for (int i=0;i<m;i++) {
            scanf ("%d %d %d",&flag,&l,&r);
            if (l>r) swap(l,r);
            if (flag==0) update(1,l,r);
            else printf ("%lld
",query(1,l,r));
        }
        printf ("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhanglichen/p/12309223.html