BZOJ 3211【线段树】

题意:
n个数,m个操作。
1,L,R  询问[L , R] 的总和。
2,L,R  将区间所有数都开根号。
思路:
区间和简单。
主要就是一个 区间所有元素相同的标记Same ,但是这样是不是要求太高?
sqrt 好像就算是1e9,也down的非常快到1了,且这里还没有区间加。
so,只要考虑标记区间是否都是1/0就足够了。

水题。

#include
using namespace std;
typedef long long LL;
const int N=1e5+10;

struct Seg{
    int Left,Right;
    int Flag;
    LL Sum;
}q[N*4];

void Build(int num,int Left,int Right){
    q[num].Left=Left;q[num].Right=Right;
    if(Left == Right){
        scanf("%lld",&q[num].Sum);
        if(q[num].Sum==0 || q[num].Sum==1)
            q[num].Flag=1;
        return;
    }
    int Mid=(Left+Right)>>1;
    Build(num<<1,Left,Mid);
    Build(num<<1|1,Mid+1,Right);
    q[num].Sum=q[num<<1].Sum+q[num<<1|1].Sum;
    q[num].Flag=q[num<<1].Flag&q[2*num|1].Flag;
}

void Update(int num,int Left,int Right)
{
    if(q[num].Flag) return;
    if(q[num].Left==q[num].Right)
    {
        q[num].Sum=sqrt(q[num].Sum);
        if(q[num].Sum==0||q[num].Sum==1) q[num].Flag=1;
        return;
    }
    int Mid=(q[num].Left+q[num].Right)>>1;
    if(Mid>=Right) Update(num<<1,Left,Right);
    else if(Mid=Left && q[num].Right<=Right)
        return q[num].Sum;
    int Mid=(q[num].Left+q[num].Right)>>1;
    if(Mid>=Right) return Query(num<<1,Left,Right);
    else if(Mid


转载于:https://www.cnblogs.com/keyboarder-zsq/p/6777341.html

你可能感兴趣的:(BZOJ 3211【线段树】)