bzoj3211: 花神游历各国 线段树

题意:给你n个数,1,查询区间和,2,把区间每个数开根
题解:可以发现1e9开5次根就变成1了,所以不用lazy直接暴力更新到叶子节点即可,当这个区间每个数都是0或1就不用下传了,

/**************************************************************
    Problem: 3211
    User: walfy
    Language: C++
    Result: Accepted
    Time:2408 ms
    Memory:4820 kb
****************************************************************/
 
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
//#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define fio ios::sync_with_stdio(false);cin.tie(0)
template<typename T>
inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>
inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
 
using namespace std;
 
const double eps=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=100000+10,maxn=400000+10,inf=0x3f3f3f3f;
 
struct segtree{
    ll val[N<<2];bool ok[N<<2];
    void pushup(int rt)
    {
        val[rt]=val[rt<<1]+val[rt<<1|1];
        ok[rt]=(ok[rt<<1]&ok[rt<<1|1]);
    }
    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            scanf("%lld",&val[rt]);
            if(val[rt]==0||val[rt]==1)ok[rt]=1;
            return ;
        }
        int m=(l+r)>>1;
        build(ls);build(rs);
        pushup(rt);
    }
    void update(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R&&ok[rt])return ;
        if(l==r)
        {
            val[rt]=sqrt(val[rt]);
            if(val[rt]==0||val[rt]==1)ok[rt]=1;
            return ;
        }
        int m=(l+r)>>1;
        if(L<=m)update(L,R,ls);
        if(m<R)update(L,R,rs);
        pushup(rt);
    }
    ll query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)return val[rt];
        int m=(l+r)>>1;
        ll ans=0;
        if(L<=m)ans+=query(L,R,ls);
        if(m<R)ans+=query(L,R,rs);
        return ans;
    }
}tree;
int main()
{
    int n;scanf("%d",&n);
    tree.build(1,n,1);
    int q;scanf("%d",&q);
    while(q--)
    {
        int op,l,r;
        scanf("%d%d%d",&op,&l,&r);
        if(op==1)printf("%lld\n",tree.query(l,r,1,n,1));
        else tree.update(l,r,1,n,1);
    }
    return 0;
}
/********************
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
********************/
posted @ 2018-08-08 10:15  walfy  阅读(262)  评论(0编辑  收藏  举报