题目链接:https://vjudge.net/problem/HDU-4027

A 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 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? —— 线段树 区间修改的更多相关文章

  1. 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 ...

  2. 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 ...

  3. HDU4027 Can you answer these queries? 线段树

    思路:http://www.cnblogs.com/gufeiyang/p/4182565.html 写写线段树 #include <stdio.h> #include <strin ...

  4. 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 ...

  5. HDU-4027-Can you answer these queries?线段树+区间根号+剪枝

    传送门Can you answer these queries? 题意:线段树,只是区间修改变成 把每个点的值开根号: 思路:对[X,Y]的值开根号,由于最大为 263.可以观察到最多开根号7次即为1 ...

  6. 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序加上一个线 ...

  7. 题解报告: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 ...

  8. poj 2528 线段树区间修改+离散化

    Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...

  9. E - Just a Hook HDU - 1698 线段树区间修改区间和模版题

    题意  给出一段初始化全为1的区间  后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...

随机推荐

  1. SSRS ( .rdl文件)如何动态的设置导出Excel文件中的工作表标签名

    要实现以上效果,则在Tablix属性里设置 参考:https://dotblogs.com.tw/ricochen/archive/2012/06/14/72798.aspx

  2. mysql数据库中的索引有那些、有什么用

    本文主要讲述了如何加速动态网站的MySQL索引分析和优化. 一.什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第 ...

  3. 字典树模板题 POJ 2503

    #include <cstdio> #include <cstring> ],fr[]; int st; struct Tire{ ]; ]; }node[]; void in ...

  4. ubuntu使用git提交github时,执行pull或者push命令要重新输入用户名和密码

    ubuntu使用git提交github时,执行pull或者push命令要重新输入用户名和密码: 1:问题现象: hlp@hlp:~/code/github_code/catch_imooc1$ git ...

  5. Eval 和 Bind 的区别

    原文发布时间为:2008-10-20 -- 来源于本人的百度文章 [由搬家工具导入] 据绑定表达式包含在 <%# 和 %> 分隔符之内,并使用 Eval 和 Bind 函数。 Eval 函 ...

  6. virtualBox下Centos系统扩展磁盘空间

    (1)查看空间容量: 打开windows命令终端.然后打开virtualbox安装目录,找到VBoxManage.exe,拖动到终端里面.输入命令:list hdds,回车. 我安装的位置是 : C: ...

  7. 最短路——Dijkstra算法

    模板 水模板ing #include <cstdio> #include <cstring> #include <algorithm> #include <i ...

  8. POJ 1422【最小路覆盖数】

    题意: 背景: 小镇有n个路口,空降兵可以在任意路口降落.有m条通往别的路口的单向边,但是不会出现循环. 问最少空降多少个士兵可以走完所有路口. 数据输入: 测试组数 t 每组有: 路口数 n 边数 ...

  9. Java调用WSDL接口

    1.首先准备jar包: 2.代码调用如下: String url="url地址"; QName qName=new QName("命名空间","接口名 ...

  10. sql 语句哪里添加单引号问题

    1.sql 语句哪里添加单引号问题,哪些地方必须加双引号,否则sql语句会报错? :涉及varchar的值的时候,必须有单引号包括varchar值.int等其他字段类型,则不需要加单引号包括. 如: ...