HDU4027 Can you answer these queries? —— 线段树 区间修改
题目链接:https://vjudge.net/problem/HDU-4027
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 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.
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 8
Sample Output
Case #1:
19
7
6
题解:
1.因为对区间的操作是:对每个数进行开根,所以不能像以前加减操作那样,也直接对区间的和进行操作(因为:a+b=sum 不能推出 根号(a)+根号(b) = 根号(a+b))。
2.根据上一点,所以在线段树中,我们只能对一段区间一直更新到每一个元素,然后再push_up求和。但是,如果每个操作都如此,那复杂度得多大?直接用数组维护比线段树更快,那要线段树何用?
3.再回看题目,数据最大为2^64,然后操作是对其开根,我们可以知道对1开根还是1,即当一个值是1时,我们不需要对其进行操作了。推广到一个区间:如果这个区间的所有元素都为1,那么我们也不需要再对这个区间进行操作。那么我们对2^64逐次开根:2^32 2^16 2^8 2^8 2^4 2^2 2^1 1,可以发现,一个数最多只需开7次根就会变成1,操作量很小了。所以:利用线段树进行维护,当一段区间的所有元素都为1,那么我们直接返回;否则更新至叶子结点(深入到每个元素)。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 1e5+; LL sum[MAXN<<]; void push_up(int u)
{
sum[u] = sum[u*] + sum[u*+];
} void build(int u, int l, int r)
{
if(l==r)
{
scanf("%lld", &sum[u]);
return;
} int mid = (l+r)>>;
build(u*, l, mid);
build(u*+, mid+, r);
push_up(u);
} void attack(int u, int l, int r, int x, int y)
{
if(l==r)
{
sum[u] = (LL)sqrt(sum[u]);
return;
}
//如果这段区域的每个值都为1,那么就无需再执行操作了
if(x<=l && r<=y && sum[u]==1LL*(r-l+)) return; int mid = (l+r)>>;
if(x<=mid) attack(u*, l, mid, x, y);
if(y>=mid+) attack(u*+, mid+, r, x, y);
push_up(u);
} LL query(int u, int l, int r, int x, int y)
{
if(x<=l && r<=y)
return sum[u]; LL ret = ;
int mid = (l+r)>>;
if(x<=mid) ret += query(u*, l, mid, x, y);
if(y>=mid+) ret += query(u*+, mid+, r, x, y);
return ret;
} int main()
{
int n, m, kase = ;
while(scanf("%d", &n)!=EOF)
{
build(, , n);
scanf("%d", &m);
printf("Case #%d:\n", ++kase);
for(int i = ; i<=m; i++)
{
LL op, x, y;
scanf("%lld%lld%lld", &op, &x, &y);
int xx = min(x, y), yy = max(x, y);
if(op==) attack(, , n, xx, yy );
else printf("%lld\n", query(, , n, xx, yy) );
}
printf("\n");
}
}
HDU4027 Can you answer these queries? —— 线段树 区间修改的更多相关文章
- 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 ...
- HDU4027 Can you answer these queries?(线段树 单点修改)
A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use ...
- HDU4027 Can you answer these queries? 线段树
思路:http://www.cnblogs.com/gufeiyang/p/4182565.html 写写线段树 #include <stdio.h> #include <strin ...
- hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和
Can you answer these queries? Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...
- HDU-4027-Can you answer these queries?线段树+区间根号+剪枝
传送门Can you answer these queries? 题意:线段树,只是区间修改变成 把每个点的值开根号: 思路:对[X,Y]的值开根号,由于最大为 263.可以观察到最多开根号7次即为1 ...
- Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)
题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...
- 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)
Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...
- poj 2528 线段树区间修改+离散化
Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...
- E - Just a Hook HDU - 1698 线段树区间修改区间和模版题
题意 给出一段初始化全为1的区间 后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...
随机推荐
- idea 中使用 出现 svn: E155036
在idea中使用svn checkout时 svn出现如上错误. 原因本地的工作副本太旧.command line进入本地工作副本的根目录,执行svn upgrade后 重启idea就可以了.
- 火狐插件youdao word capturer无法删除。
[]火狐插件youdao word capturer无法删除. 魔芋记录一下: []一直无法删除,就网上找了下. 网上解释说是:有道词典自己安装的插件,所以火狐无法管理. 用来帮助 ...
- 大数据学习——点击流日志每天都10T,在业务应用服务器上,需要准实时上传至(Hadoop HDFS)上
点击流日志每天都10T,在业务应用服务器上,需要准实时上传至(Hadoop HDFS)上 1需求说明 点击流日志每天都10T,在业务应用服务器上,需要准实时上传至(Hadoop HDFS)上 2需求分 ...
- jquery取当前节点的上级ID
- python re 正则提取中文
需求: 提取文本中的中文和数字字母(大小写都要),即相当于删除所有标点符号. 其中new是原字符串 news = re.findall(r'[\u4e00-\u9fa5a-zA-Z0-9]',new)
- zoj 2001 Adding Reversed Numbers
Adding Reversed Numbers Time Limit: 2 Seconds Memory Limit: 65536 KB The Antique Comedians of M ...
- [luoguP2015] 二叉苹果树(DP)
传送门 貌似是个树形背包... 好像吧.. f[i][j]表示节点i选条边的最优解 #include <cstdio> #include <cstring> #include ...
- hdu 4790 数学
/* 题意:给你二个区间[a,b]和[c,d] 分别从中选一个数x和y使的(x+y)%p=m; 可以这样来求,先求出(0->b和0->d区间段的值)-(区间0->a-1和0-> ...
- msp430入门编程42
msp430中C语言的软件工程--事件触发程序结构
- linux 常见名词及命令(一)
linux PK wondows 稳定且有效率.免费或少许费用.漏洞少且修补快.多任务多用户. 安全的用户及文件权限策略.适合小内核程序的嵌入系统.相对不耗资源. 热门的开源系统 红帽企业系统(R ...