Can you answer these queries? HDU

Can you answer these queries? HDU - 4027

传送门

线段树区间求根,区间求和

因为一个数long long范围的数在十次以内的开根号运算后肯定会变为1,所以但一个区间的最大值变为1后就不需要对这个区间开根号运算了

#include <cstdio>
#include <iostream>
#include <queue>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
#define ll long long
#define P pair<int,int>
const int N=1e6+10;
const ll INF =  ~(1LL<<63);
ll a[N];
struct SegmentTree{
    int l,r;
    ll sum;
    ll col;
}t[N*4];
void pushup(int p)
{
    t[p].col = t[p*2].col && t[p*2+1].col;
    t[p].sum = t[p*2].sum + t[p*2+1].sum;
}
void build(int p,int l,int r)
{
    t[p].l = l;
    t[p].r = r;
    if(t[p].l == t[p].r)
    {
        t[p].sum = a[l];
        if(a[l]==1)
            t[p].col = 1;
        else
            t[p].col = 0;
        return;
    }
    int mid = (l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    pushup(p);
}
void change(int p,int l,int r)
{
    if(t[p].l == t[p].r)
    {
        t[p].sum = (ll)sqrt(t[p].sum);
        if(t[p].sum == 1)
            t[p].col = 1;
        return ;
    }
    int mid = (t[p].l+t[p].r)/2;
    if(l<=mid && !t[p*2].col) change(p*2,l,r);
    if(r>mid && !t[p*2+1].col) change(p*2+1,l,r);
    pushup(p);
}
ll ask(int p,int l,int r)
{
    if(l<=t[p].l&&r>=t[p].r)
        return t[p].sum;
    int mid = (t[p].l+t[p].r)/2;
    ll sum = 0;
    if(l<=mid) sum += ask(p*2,l,r);
    if(r>mid) sum += ask(p*2+1,l,r);
    return sum;
}
int main()
{
    ios::sync_with_stdio(false);
    int kase = 0,n,m;
    while(cin >> n)
    {
        for(int i=1;i<=n;i++)
        {
            cin >> a[i];
        }
        build(1,1,n);

        cin >> m;
        cout << "Case #" << ++kase << ":
";

        while(m--)
        {
            int l,r,flag;
            cin >> flag >> l >> r;
            if(l>r)
                swap(l,r);
            if(flag==0)
                change(1,l,r);
            else
                cout << ask(1,l,r) << "
";
        }
        cout << "
";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hh13579/p/12383213.html