标签:线段树
10 1 2 3 4 5 6 7 8 9 10 5 0 1 10 1 1 10 1 1 5 0 5 8 1 4 8
Case #1: 19 7 6
思路:因为一个数开一定的根号后是1 ,那么就不会再变了,一段区间这样都是一就没必要改变了,所以这样可以节约时间,还有这份代码用G++交超时,c++交过
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)
#define eps 1e-8
typedef __int64 ll;
#define fre(i,a,b) for(i = a; i <b; i++)
#define free(i,b,a) for(i = b; i >= a;i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define ssf(n) scanf("%s", n)
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define bug pf("Hi\n")
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000005
struct stud{
int le,ri;
ll len,sum;
}f[N*4];
ll a[N];
inline void pushup(int pos)
{
f[pos].sum=f[L(pos)].sum+f[R(pos)].sum;
}
void build(int pos,int le,int ri)
{
f[pos].le=le;
f[pos].ri=ri;
f[pos].len=ri-le+1;
if(le==ri)
{
f[pos].sum=a[le];
return ;
}
int mid=MID(le,ri);
build(L(pos),le,mid);
build(R(pos),mid+1,ri);
pushup(pos);
}
void hello(int pos) //把这一个区间的数都开根号
{
if(f[pos].len==f[pos].sum)
return;
if(f[pos].le==f[pos].ri)
{
f[pos].sum=(ll)(sqrt(f[pos].sum+0.0));
return ;
}
hello(L(pos));
hello(R(pos));
pushup(pos);
}
void update(int pos,int le,int ri)
{
if(f[pos].len==f[pos].sum)
return ;
if(f[pos].le==le&&f[pos].ri==ri)
{
hello(pos);
return ;
}
int mid=MID(f[pos].le,f[pos].ri);
if(mid>=ri)
update(L(pos),le,ri);
else
if(mid<le)
update(R(pos),le,ri);
else
{
update(L(pos),le,mid);
update(R(pos),mid+1,ri);
}
pushup(pos);
}
ll query(int pos,int le,int ri)
{
if(f[pos].le==le&&f[pos].ri==ri)
return f[pos].sum;
int mid=MID(f[pos].le,f[pos].ri);
if(mid>=ri)
return query(L(pos),le,ri);
else
if(mid<le)
return query(R(pos),le,ri);
else
return (ll)(query(L(pos),le,mid)+query(R(pos),mid+1,ri));
}
int main()
{
int i,j,n,m,ca=0;
while(~sf(n))
{
fre(i,1,n+1)
scanf("%I64d",&a[i]);
build(1,1,n);
sf(m);
pf("Case #%d:\n",++ca);
int op,le,ri;
while(m--)
{
sfff(op,le,ri);
if(le>ri) swap(le,ri);
if(op)
pf("%I64d\n",query(1,le,ri));
else
update(1,le,ri);
}
pf("\n");
}
return 0;
}
HDU 4027 Can you answer these queries(线段树 成段更新)
标签:线段树
原文地址:http://blog.csdn.net/u014737310/article/details/44517149