HDU 4027 Can you answer these queries? 线段树 区间修改 区间查询

http://blog.csdn.net/u013368721/article/details/32324211

注意到一个性质,一个数开方,6次内必变为1或0,然后就可以暴力地跑线段树了

出题人没保证x <= y,呵呵了

My code

//Hello. I'm Peter.
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline ll readLL(){
    ll x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

#define N 100010
int n, m;
ll a[N];

#define lch id<<1
#define rch id<<1|1
#define mid ((l+r)>>1)
struct Segment_Tree{
    bool fine;
    ll sum;
}tree[N<<2];

void plant_tree(int id,int l,int r){
    if(l == r){
        tree[id].sum = a[l];
        if(a[l] == 0 || a[l] == 1) tree[id].fine = 1;
        else tree[id].fine = 0;

        return;
    }

    plant_tree(lch, l ,mid);
    plant_tree(rch, mid + 1, r);

    tree[id].sum = tree[lch].sum + tree[rch].sum;
    tree[id].fine = tree[lch].fine & tree[rch].fine;
}

void update(int id,int l,int r,int ql,int qr){
    if(ql == l && qr == r){
        if(tree[id].fine) return;

        if(l == r){
            if(tree[id].sum == 0 || tree[id].sum == 1) tree[id].fine = 1;
            else tree[id].sum = (double)sqrt((double)tree[id].sum);

            return;
        }

        if(!tree[lch].fine) update(lch, l, mid, ql, mid);
        if(!tree[rch].fine) update(rch, mid + 1, r, mid + 1, qr);

        tree[id].sum = tree[lch].sum + tree[rch].sum;
        tree[id].fine = tree[lch].fine & tree[rch].fine;

        return;
    }

    if(qr <= mid) update(lch, l, mid, ql, qr);
    else if(mid < ql) update(rch, mid + 1, r, ql, qr);
    else update(lch, l, mid, ql, mid), update(rch, mid + 1, r, mid + 1, qr);

    tree[id].sum = tree[lch].sum + tree[rch].sum;
    tree[id].fine = tree[lch].fine & tree[rch].fine;
}

ll query(int id,int l,int r,int ql,int qr){
    if(ql == l && qr ==r) return tree[id].sum;

    if(qr <= mid) return query(lch, l, mid, ql, qr);
    else if(mid < ql) return query(rch, mid + 1, r, ql, qr);
    else return query(lch, l, mid, ql, mid) + query(rch, mid + 1, r, mid + 1, qr);
}

#define input freopen("/Users/peteryuanpan/data.txt","r",stdin)

int main(){
    //input;

    int kase = 1;
    while(~scanf("%d",&n)){
        printf("Case #%d:\n",kase++);

        for(int i = 1; i <= n; i++) a[i] = readLL();
        plant_tree(1,1,n);

        m = read();
        for(int i = 1; i <= m; i++){
            int ty = read();
            if(ty == 0){
                int x, y;
                x = read(), y = read();
                if(x > y) swap(x, y);

                update(1, 1, n, x, y);
            }
            else{
                int x, y;
                x = read(), y = read();
                if(x > y) swap(x, y);

                ll ans = query(1, 1, n, x, y);
                printf("%I64d\n",ans);
            }
        }
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(线段树)