HDU-4027 Can you answer these queries?(线段树区间开方)
Posted jiamian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-4027 Can you answer these queries?(线段树区间开方)相关的知识,希望对你有一定的参考价值。
http://acm.hdu.edu.cn/showproblem.php?pid=4027
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Problem Description
You are asked to answer the queries that the sum of the endurance of a consecutive part of the battleship line.
Notice that the square root operation should be rounded down to integer.
Input
The input contains several test cases, terminated by EOF.
For each test case, the first line contains a single integer N, denoting there are N battleships of evil in a line. (1 <= N <= 100000)
The second line contains N integers Ei, indicating the endurance value of each battleship from the beginning of the line to the end. You can assume that the sum of all endurance value is less than 2 63.
The next line contains an integer M, denoting the number of actions and queries. (1 <= M <= 100000)
For the following M lines, each line contains three integers T, X and Y. The T=0 denoting the action of the secret weapon, which will decrease the endurance value of the battleships between the X-th and Y-th battleship, inclusive. The T=1 denoting the query of the commander which ask for the sum of the endurance value of the battleship between X-th and Y-th, inclusive.
Output
For each test case, print the case number at the first line. Then print one line for each query. And remember follow a blank line after each test case.
Sample Input
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
Sample Output
Case #1: 19 7 6
解题思路:
很明显的线段树
很容易想到区间更新的lazy思想,但是这道题的更新并不是简单的加减乘除,而是开方。但是开方的话我们无法通过延迟更新来减少时间复杂度,也就是说lazy思想在这里并不是太试用。
那么我们想一想算术平方根,sqrt(1)=1,且考虑到数据范围为2的63次方,也就是说这个数最多只能开7次平方,因为接下来如何再开方都是1了。
所以我们就可以从这点入手,当更新时我们不延迟更新了,需要我们判断一下是否需要更新。
如果在这个区间内SegTree[rt].sum = SegTree[rt].r-SegTree[rt].l+1(就是区间内有点都为1)很明显这个时候不用更新区间,那就直接return。
如果这个区间可以更新,那就直接更新这个区间。所以每次更新都更新到叶子结点,维护区间和就行了。
除此之外,这题也有不少的坑点:
1:要区分好那些数据是long long,那些是int
2:注意每个样例后都要输出一个空行
3:注意输入x,y后要检查是否x<=y,如果x>y,要交换x和y(最坑的点,做过那么多的区间查询,这是我遇见的第一个还设置这种坑的,有意思么。。。)
代码如下:
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <queue> 9 #include <set> 10 #include <map> 11 #include <math.h> 12 const int INF=0x3f3f3f3f; 13 typedef long long LL; 14 const int mod=1e9+7; 15 //const double PI=acos(-1); 16 const int maxn=1e5+10; 17 using namespace std; 18 //ios::sync_with_stdio(false); 19 // cin.tie(NULL); 20 21 int n,m; 22 struct node 23 24 int l; 25 int r; 26 LL sum; 27 SegTree[maxn<<2]; 28 29 void PushUp(int rt) 30 31 SegTree[rt].sum=SegTree[rt<<1].sum+SegTree[rt<<1|1].sum; 32 33 34 void Build(int l,int r,int rt) 35 36 SegTree[rt].l=l; 37 SegTree[rt].r=r; 38 if(l==r) 39 40 scanf("%lld",&SegTree[rt].sum); 41 return; 42 43 int mid=(l+r)>>1; 44 Build(l,mid,rt<<1); 45 Build(mid+1,r,rt<<1|1); 46 PushUp(rt); 47 48 49 void Update(int L,int R,int rt) 50 51 int l=SegTree[rt].l; 52 int r=SegTree[rt].r; 53 if(L<=l&&R>=r) 54 55 if(SegTree[rt].sum==SegTree[rt].r-SegTree[rt].l+1)//说明该区间全是1,没必要开方 56 return ; 57 58 if(l==r)//该区间不为1 59 60 SegTree[rt].sum=(LL)sqrt(SegTree[rt].sum*1.0); 61 return ; 62 63 int mid=(l+r)>>1; 64 if(L<=mid) 65 Update(L,R,rt<<1); 66 if(R>mid) 67 Update(L,R,rt<<1|1); 68 PushUp(rt); 69 70 71 LL Query(int L,int R,int rt) 72 73 int l=SegTree[rt].l; 74 int r=SegTree[rt].r; 75 if(L<=l&&R>=r) 76 77 return SegTree[rt].sum; 78 79 LL SUM=0; 80 int mid=(l+r)>>1; 81 if(L<=mid) 82 SUM+=Query(L,R,rt<<1); 83 if(R>mid) 84 SUM+=Query(L,R,rt<<1|1); 85 return SUM; 86 87 88 int main() 89 90 //freopen("sample.txt","r",stdin); 91 int num=1; 92 while(~scanf("%d",&n)) 93 94 printf("Case #%d:\n",num++); 95 Build(1,n,1); 96 scanf("%d",&m); 97 for(int i=1;i<=m;i++) 98 99 int f,x,y; 100 scanf("%d %d %d",&f,&x,&y); 101 if(x>y)//坑点 102 swap(x,y); 103 if(f==0) 104 105 Update(x,y,1); 106 107 else if(f==1) 108 109 printf("%lld\n",Query(x,y,1)); 110 111 112 printf("\n");//坑点 113 114 return 0; 115
以上是关于HDU-4027 Can you answer these queries?(线段树区间开方)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 4027 Can you answer these queries? (线段树)
HDU-4027 Can you answer these queries?(线段树区间开方)
HDU 4027 Can you answer these queries?
Can you answer these queries? HDU - 4027