bzoj3211: 花神游历各国(线段树) 同codevs2492

3211: 花神游历各国

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 3628  Solved: 1326
[Submit][Status][Discuss]

Description

 

Input

 

Output

每次x=1时,每行一个整数,表示这次旅行的开心度

 

Sample Input

4

1 100 5 5

5

1 1 2

2 1 2

1 1 2

2 2 3

1 1 4

Sample Output

101

11

11

HINT

 

对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9

/*
线段树区间开根,区间求和
以为一个一个开根很耗时间,所以要优化
想到一个数开几次根就到一了,所以用个flag记录当前是否是0或1
是的话就 return 快很多。 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

#define N 100010
#define ll long long

using namespace std;
ll n,m,ans;
struct tree
{
    ll l,r,sum;
    bool flag;
}tr[N<<2];

inline ll read()
{
    ll x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

inline void pushup(ll k)
{
    tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    tr[k].flag=tr[k<<1].flag&tr[k<<1|1].flag;
}

void build(ll k,ll l,ll r)
{
    tr[k].l=l;tr[k].r=r;tr[k].sum=0;
    if(l==r)
    {
        tr[k].sum=read();
        if(tr[k].sum==0 || tr[k].sum==1) tr[k].flag=1;
        return;
    }
    ll mid=(tr[k].r+tr[k].l)>>1;
    build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    pushup(k);
}

void change(ll k,ll l,ll r)
{
    if(tr[k].flag) return;
    if(tr[k].l==tr[k].r)
    {
        tr[k].sum=(ll) sqrt(tr[k].sum);
        if(tr[k].sum==0 || tr[k].sum==1) tr[k].flag=1;
        return;
    }
    ll mid=(tr[k].l+tr[k].r)>>1;
    if(r<=mid) change(k<<1,l,r);
    else if(l>mid) change(k<<1|1,l,r);
    else change(k<<1,l,mid),change(k<<1|1,mid+1,r);
    pushup(k);
}

ll query(ll k,ll l,ll r)
{
    if(tr[k].l==l && tr[k].r==r)
    return tr[k].sum;
    pushup(k);
    ll mid=(tr[k].r+tr[k].l)>>1;
    if(r<=mid) return query(k<<1,l,r);
    else if(l>mid) return query(k<<1|1,l,r);
    else return query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
}

int main()
{
     long long x,y,z;
     n=read();build(1,1,n);
     m=read();
     while(m--)
     {
         x=read();y=read();z=read();
         if(y>z) swap(y,z);
         if(x==1) printf("%lld
",query(1,y,z));
         else change(1,y,z);
     }
     return 0;
}