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