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;
}