hdu 4027 Can you answer these queries? (区间线段树,区间数开方与求和,经典题目)
Can you answer these queries?
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 10249 Accepted Submission(s): 2350Problem DescriptionA
lot of battleships of evil are arranged in a line before the battle.
Our commander decides to use our secret weapon to eliminate the
battleships. Each of the battleships can be marked a value of endurance.
For every attack of our secret weapon, it could decrease the endurance
of a consecutive part of battleships by make their endurance to the
square root of it original value of endurance. During the series of
attack of our secret weapon, the commander wants to evaluate the effect
of the weapon, so he asks you for help.
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.
InputThe 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 263.
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.OutputFor
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 8Sample Output
Case #1:
19
7
6Source
之前听说过很多神级线段树的题,最后都是暴力拼循环节,今天难得见一个入门级别的,也算涨姿势了~
题意:给定n个数(1~100000),两种操作(1~100000)0 or 1 ,0操作是把给定区间内的数都变成原来的开方(向下取整),1操作,询问区间内的数的总和;
突破点:所有数据和的范围是2的63此方,大神们发现开方六七次以后,这些数就都变成1了~所以就不需要再向下更新了,
那么判定不需要更新的条件就是:该节点下的区间总和与该区间长度相等,那么它们妥妥都是1了,就可以返回。
但是本题坑坑比较多~
1坑:给定区间 Xth 与 Yth大小关系不定,记得用下swap~,不然就是RE(非法访问)。
2坑 : 每组测试实例最后还需要多输出一个空行~
0.0也怪不细心~
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <climits>
#include <queue>
#define ll long long using namespace std; const int MAX = ;
ll num[MAX]; struct nodes
{
int left,right;
ll large;
} tree[MAX*]; void pushup(int root)
{
tree[root].large = tree[root*].large + tree[root*+].large;
}
void build(int root,int left,int right)
{
tree[root].left = left;
tree[root].right = right;
if(left == right)
{
tree[root].large = num[left];
return;
} int mid = (left+right)/; build(*root,left,mid);
build(*root+,mid+,right); pushup(root);
} void update(int root,int left,int right)
{
if(tree[root].large == tree[root].right - tree[root].left + )
return;
if(tree[root].right == tree[root].left)
{
tree[root].large = (ll)sqrt(tree[root].large);
return;
}
int mid = (tree[root].left+tree[root].right)/;
if(left <= mid && right > mid)
{
update(*root,left,mid);
update(*root+,mid+,right);
}
else if(left > mid)
{
update(*root+,left,right);
}
else
{
update(*root,left,right);
}
pushup(root);
} ll query(int root ,int left,int right)
{
if(tree[root].large == tree[root].right - tree[root].left + )
{
return right - left + ;
}
if(left == tree[root].left && right == tree[root].right)
{
return tree[root].large;
}
int mid = (tree[root].left+tree[root].right)/;
ll ans = ;
if(right > mid && left <= mid)
{
ans += query(*root,left,mid);
ans += query(*root+,mid+,right);
}
else if(left > mid)
{
ans += query(*root+,left,right);
}
else
{
ans += query(*root,left,right);
}
return ans;
} int main(void)
{
int i,cmd,x,y,n,q,cnt= ;
while(scanf("%d",&n) != -)
{
for(i = ; i <= n; i++)
scanf("%lld",&num[i]);
build(,,n);
scanf("%d",&q);
printf("Case #%d:\n",cnt++);
for(i = ; i <q; i++)
{
scanf("%d %d %d",&cmd,&x,&y);
if(y < x)
swap(x,y);
if(cmd)
printf("%lld\n",query(,x,y));
else
update(,x,y);
}
printf("\n");
}
return ;
}
精简版
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <climits>
#include <queue>
#define ll long long using namespace std; struct Segment_T
{
static const int MAX = 1e5+;
ll num[MAX];
struct nodes
{
int lt,rt;
ll add,sum;
} T[MAX*]; Segment_T(){} void pushup(int R)
{
T[R].sum = T[R<<].sum + T[R<<|].sum;
}
void pushdown(int R)
{
if(T[R].add)
{
T[R<<].add += T[R].add;
T[R<<|].add += T[R].add;
T[R<<].sum += T[R].add * (T[R<<].rt - T[R<<].lt + );
T[R<<|].sum += T[R].add * (T[R<<|].rt - T[R<<|].lt + );
T[R].add = ;
}
}
void build(int R,int lt,int rt)
{
T[R].lt = lt;
T[R].rt = rt;
if(lt == rt)
{
T[R].sum = num[lt];
return;
}
int mid = (lt+rt)>>; build(R<<,lt,mid);
build(R<<|,mid+,rt); pushup(R);
}
void update(int R,int lt,int rt)
{
if(T[R].sum == T[R].rt - T[R].lt + )
return;
if(T[R].rt == T[R].lt)
{
T[R].sum = (ll)sqrt(T[R].sum); //返回操作处
return;
}
int mid = (T[R].lt+T[R].rt)>>;
if(lt <= mid && rt > mid)
{
update(R<<,lt,mid);
update(R<<|,mid+,rt);
}
else if(lt > mid)
update(R<<|,lt,rt);
else
update(R<<,lt,rt);
pushup(R);
}
ll query(int R,int lt,int rt)
{
if(T[R].sum == T[R].rt - T[R].lt + )
{
return rt - lt + ;
}
if(lt == T[R].lt && rt == T[R].rt)
{
return T[R].sum; //返回操作处
}
int mid = (T[R].lt+T[R].rt)>>;
ll ans = ;
if(rt > mid && lt <= mid)
ans = query(R<<,lt,mid) + query(R<<|,mid+,rt);
else if(lt > mid)
ans += query(R<<|,lt,rt);
else
ans += query(R<<,lt,rt);
return ans;
}
};
Segment_T Tr;
int main(void)
{
int i,cmd,x,y,n,q,cnt= ;
while(scanf("%d",&n) != -)
{
for(i = ; i <= n; i++)
scanf("%lld",&Tr.num[i]);
Tr.build(,,n);
scanf("%d",&q);
printf("Case #%d:\n",cnt++);
for(i = ; i <q; i++)
{
scanf("%d %d %d",&cmd,&x,&y);
if(y < x)
swap(x,y);
if(cmd)
printf("%lld\n",Tr.query(,x,y));
else
Tr.update(,x,y);
}
printf("\n");
}
return ;
}
hdu 4027 Can you answer these queries? (区间线段树,区间数开方与求和,经典题目)的更多相关文章
- HDU 4027—— Can you answer these queries?——————【线段树区间开方,区间求和】
Can you answer these queries? Time Limit:2000MS Memory Limit:65768KB 64bit IO Format:%I64d & ...
- HDU 4027 Can you answer these queries?(线段树区间开方)
Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K ...
- HDU - 4027 Can you answer these queries?(线段树区间修改)
https://cn.vjudge.net/problem/HDU-4027 题意 给一个有初始值的数组,存在两种操作,T=0时将[L,R]的值求平方根,T=1时查询[L,R]的和. 分析 显然不符合 ...
- HDU 4027 Can you answer these queries?(线段树的单点更新+区间查询)
题目链接 题意 : 给你N个数,进行M次操作,0操作是将区间内的每一个数变成自己的平方根(整数),1操作是求区间和. 思路 :单点更新,区间查询,就是要注意在更新的时候要优化,要不然会超时,因为所有的 ...
- HDU 4027 Can you answer these queries【线段树】
<题目链接> 题目大意: 给定一段序列,现在对指定区间进行两种操作:一是对指定区间进行修改,对其中的每个数字都开根号(开根号后的数字仍然取整):二是对指定区间进行查询,查询这段区间所有数字 ...
- HDU - 4027 Can you answer these queries?(线段树)
给定一个长度为n的序列,m次操作. 每次操作 可以将一个区间内的所有数字变为它的根号. 可以查询一个区间内所有元素的和. 线段树的初级应用. 如果把一个区间内的元素都改为它的根号的话,是需要每个数字都 ...
- hdu 4027 Can you answer these queries?[线段树]
题目 题意: 输入一个 :n .(1<=n<<100000) 输入n个数 (num<2^63) 输入一个m :代表m个操作 (1<=m<<100 ...
- HDU 4027 Can you answer these queries(线段树 + 观察 )
这题主要考察观察能力. 2^63最多只需要开7次根号就会变成1,当数字变成1之后就不需要再对其进行操作. 对于含有大于1数字的区间,向下更新. 对于数字全为1的区间,直接返回. #include &l ...
- SPOJ GSS1_Can you answer these queries I(线段树区间合并)
SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...
- HDU 4027 Can you answer these queries? (线段树区间修改查询)
描述 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to u ...
随机推荐
- gdal在redhat4.4下安装
GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库.它利用抽象数据模型来表达所支持的各种文件格式.它还有一系列命令行 ...
- BASE64Encoder及BASE64Decoder查看源代码方法
一直以来Base64的加密解密都是使用sun.misc包下的BASE64Encoder及BASE64Decoder的sun.misc.BASE64Encoder/BASE64Decoder类.这人个类 ...
- Spring Cloud Config-Client 无法获取 Config-Server 在 github 上的配置文件的属性值,竟然是因为
Spring Cloud Config-Client 无法获取 Config-Server 在 github 上的配置文件的属性值,竟然是因为!!! 2018年07月23日 16:33:25 一颗很菜 ...
- 关于mybatis对实体类参数绑定参数的问题
dao层的代码: public interface SupplierMapper extends BaseMapper<SupplierDbo>{ /*List<SupplierDb ...
- MVVM基础概念和理解
在MVVM模式中,View封装UI和UI逻辑,viewmodel封装presentation逻辑,model封装业务逻辑和数据. View类 View的责任是定义屏幕上的结构和外观,在完美的情况下,v ...
- 04-2-object类型
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 理解JWT
1. JSON Web Token是什么 JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该 ...
- 跟我一起学koa之在koa中使用mongoose(四)
第一步安装mongoose,创建数据库文件夹 第二步引入mongoose,连接数据库 第三步运行项目 这个报错 只需要将es6写法变成es5写法即可 我们连接数据库,并且以post请求的方式插入数据 ...
- PHP的垃圾回收机制(开启垃圾回收机制后的优缺点是什么)
PHP的垃圾回收机制(开启垃圾回收机制后的优缺点是什么) 一.总结 一句话总结: 拿时间换空间:针对内存泄露的情况,可以节省大量的内存空间,但是由于垃圾回收算法运行耗费时间,开启垃圾回收算法会增加脚本 ...
- PAT甲级——A1038 Recover the Smallest Number
Given a collection of number segments, you are supposed to recover the smallest number from them. Fo ...