BZOJ P3211 LOJ P10128 花神游历各国【线段树】

注意到两个地方:
1. 1 , 0 开根后仍然是 1 , 0
2.任何非零数不断开根后最终一定会变为 1

所以我们在线段树当中标记一个当前区间内的数是否都是 1 或者 0 就可以了。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define SG string
#define DB double
#define LL long long
using namespace std;
inline LL Read(){
    LL X=0;char CH=getchar();bool F=0;
    while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
    while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
    return F?-X:X;
}
inline void Write(LL X){
    if(X<0)X=-X,putchar('-');
    if(X>9)Write(X/10);
    putchar(X%10+48);
}
const LL Max=1e5+5;
struct Node{
    LL X,Y,Sum,Lazy;
}Tree[Max<<3];
LL N,M,A[Max];
void MakeTree(LL P,LL X,LL Y){
    Tree[P].X=X,Tree[P].Y=Y;
    if(X==Y){
        Tree[P].Sum=A[X];
        if(Tree[P].Sum==1||Tree[P].Sum==0){
            Tree[P].Lazy=1;
        }
        return ;
    }
    MakeTree(P<<1,X,X+Y>>1);
    MakeTree(P<<1|1,(X+Y>>1)+1,Y);
    Tree[P].Sum=Tree[P<<1].Sum+Tree[P<<1|1].Sum;
    Tree[P].Lazy=Tree[P<<1].Lazy&Tree[P<<1|1].Lazy;
}
void Update(LL P,LL X,LL Y){
    if(Tree[P].Lazy==1){
        return;
    }
    if(Tree[P].X==Tree[P].Y){
        Tree[P].Sum=sqrt(Tree[P].Sum);
        if(Tree[P].Sum==1||Tree[P].Sum==0){
            Tree[P].Lazy=1;
        }
        return;
    }
    if(Y<=Tree[P<<1].Y){
        Update(P<<1,X,Y);
    } else if (Tree[P<<1|1].X<=X){
        Update(P<<1|1,X,Y);
    } else {
        Update(P<<1,X,Tree[P<<1].Y);
        Update(P<<1|1,Tree[P<<1|1].X,Y);
    }
    Tree[P].Sum=Tree[P<<1].Sum+Tree[P<<1|1].Sum;
    Tree[P].Lazy=Tree[P<<1].Lazy&Tree[P<<1|1].Lazy;
}
LL GetSum(LL P,LL X,LL Y){
    if(Tree[P].X==X&&Tree[P].Y==Y){
        return Tree[P].Sum;
    }
    if(Y<=Tree[P<<1].Y){
        return GetSum(P<<1,X,Y);
    } else if (Tree[P<<1|1].X<=X){
        return GetSum(P<<1|1,X,Y);
    } else {
        return GetSum(P<<1,X,Tree[P<<1].Y)+GetSum(P<<1|1,Tree[P<<1|1].X,Y);
    }
}
int main(){
    LL I,J,K;
    N=Read();
    for(I=1;I<=N;I++){
        A[I]=Read();
    }
    MakeTree(1,1,N);
    M=Read();
    for(I=1;I<=M;I++){
        K=Read();LL X=Read(),Y=Read();
        if(K==1){
            Write(GetSum(1,X,Y)),putchar('\n');
        } else {
            Update(1,X,Y);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/81349415