HDU - 4027 Can you answer these queries?(线段树区间修改)

https://cn.vjudge.net/problem/HDU-4027

题意

给一个有初始值的数组,存在两种操作,T=0时将[L,R]的值求平方根,T=1时查询[L,R]的和。

分析

显然不符合加法合并原理,只能考虑直接点更新,可这样就完蛋了。。突破口在于sqrt,2^63-1只需要sqrt了6、7次就变为1了,而1再sqrt也无意义。所以在更新时,只要这段区间的和等于区间长度,说明都为1,那么就不需要继续更新下去了。查询时就是区间求和。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define eps 0.0000000001
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define random(a, b) rand()*rand()%(b-a+1)+a
#define pi acos(-1)
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
const int maxn = 100000 + 10;
const int maxm = 200000 + 10;
const int mod = 998244353;
int n;
struct ND{
    int l,r;
    ll sum;
}tree[maxn<<2];
int pre;
int ans[maxn];
void pushup(int rt){
    tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
}
void pushdown(int rt){
    if(tree[rt].l==tree[rt].r){
        tree[rt].sum=1ll*sqrt(tree[rt].sum);
        return;
    }
    pushdown(rt<<1);
    pushdown(rt<<1|1);
    pushup(rt);
}
void build(int rt,int l,int r){
    tree[rt].l=l,tree[rt].r=r;
    if(l==r){
        scanf("%lld",&tree[rt].sum);
        return;
    }
    int mid=(l+r)>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
    pushup(rt);
}
void update(int rt,int L,int R){
    if(L<=tree[rt].l&&tree[rt].r<=R){
         if(tree[rt].r-tree[rt].l+1==tree[rt].sum) return;
         pushdown(rt);
         return;
    }
    int mid=(tree[rt].l+tree[rt].r)>>1;
    if(mid>=L) update(rt<<1,L,R);
    if(mid<R) update(rt<<1|1,L,R);
    pushup(rt);
}

ll query(int rt,int L,int R){
    if(L<=tree[rt].l&&tree[rt].r<=R){
        return tree[rt].sum;
    }
//    pushdown(rt);
    ll sum=0;
    int mid=(tree[rt].l+tree[rt].r)>>1;
    if(mid>=L) sum+=query(rt<<1,L,R);
    if(mid<R) sum+=query(rt<<1|1,L,R);
    return sum;
}
int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int t,cas=1;
//    scanf("%d",&t);
    while(~scanf("%d",&n)){
        build(1,1,n);
        int m;
        scanf("%d",&m);
        printf("Case #%d:\n",cas++);
        while(m--){
            int t,x,y;
            scanf("%d%d%d",&t,&x,&y);
            if(x>y) swap(x,y);
            if(t==1){
                printf("%lld\n",query(1,x,y));
            }else{
                update(1,x,y);
            }
        }
        puts("");
    }
    return 0;
}

 

posted @ 2018-09-02 10:53  litos  阅读(120)  评论(0编辑  收藏  举报