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 }
原文地址:https://www.cnblogs.com/jiamian/p/11408944.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux 实现lvs-dr在不同网段的负载均衡调度
- docker实现Mongodb复制集
- Centos7搭建LAMP+Typecho个人博客
- [Centos7]搭建postfix邮件服务器
- [Docker]手动配置docker网络
- [Centos7]使用GPG加密和解密文件
- [Centos7]设置禁ping
- [Centos7]open读取文件报错:TypeError
- [Centos7]对硬盘进行分区及自动挂载
- [Centos7]extundelete恢复误删除数据
- [Centos7]自定义开机自启脚本
- [Centos7]安装scapy模块
- [Centos7]安装rrdtool模块
- [Centos7]XlsxWriter模块安装
- [Centos7]安装pycurl