http://acm.hdu.edu.cn/showproblem.php?pid=4027
Can you answer these queries?
Total Submission(s): 8458 Accepted Submission(s): 1929
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
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
题意:
给出一排敌军的血量,每次攻击都能将范围内的敌军血量变为原来血量的算术平方根(下取整),并询问范围内敌军的血量和。
分析:
显然的线段树,但是似乎不太好设计lazy标记啊,我们想一想算术平方根,sqrt(1)=1,且64位整数范围内最多6次就变到1了,那么只要区间内的数都为1,我就不用更新这个区间了,所以每次更新都更新到叶子结点,维护区间和就行了。数据里没有0,不过X>Y这种trick有意思吗?
/*
*
* Author : fcbruce
*
* Date : 2014-08-27 16:46:52
*
*/
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10
#ifdef _WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define maxm
#define maxn 100007
using namespace std;
LL sum[maxn<<2];
inline void pushup(itn k)
{
sum[k]=sum[k*2+1]+sum[k*2+2];
}
void build(int k,int l,int r)
{
if (r-l==1)
{
scanf( lld ,&sum[k]);
return ;
}
build(k*2+1,l,l+r>>1);
build(k*2+2,l+r>>1,r);
pushup(k);
}
void update(int a,int b,int k,int l,int r)
{
if (b<=l || r<=a) return ;
if (sum[k]==r-l) return ;
if (r-l==1)
{
sum[k]=(LL)sqrt(sum[k]);
return ;
}
update(a,b,k*2+1,l,l+r>>1);
update(a,b,k*2+2,l+r>>1,r);
pushup(k);
}
LL query(itn a,int b,itn k,int l,int r)
{
if (b<=l || r<=a) return 0;
if (a<=l && r<=b) return sum[k];
return query(a,b,k*2+1,l,l+r>>1)+query(a,b,k*2+2,l+r>>1,r);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("/home/fcbruce/文档/code/t","r",stdin);
#endif // ONLINE_JUDGE
int n,m,__=0;
while (~scanf( "%d",&n))
{
printf( "Case #%d:\n",++__);
build(0,0,n);
itn q,a,b;
scanf( "%d",&m);
while (m--)
{
scanf( "%d%d%d",&q,&a,&b);
if (a>b) swap(a,b);
a--;
if (q)
printf( lld "\n",query(a,b,0,0,n));
else
update(a,b,0,0,n);
}
putchar( '\n');
}
return 0;
}
HDU 4027 Can you answer these queries? (线段树)
原文地址:http://blog.csdn.net/u012965890/article/details/38875033