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): 2350

Problem Description
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.

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

之前听说过很多神级线段树的题,最后都是暴力拼循环节,今天难得见一个入门级别的,也算涨姿势了~

题意:给定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? (区间线段树,区间数开方与求和,经典题目)的更多相关文章

  1. HDU 4027—— Can you answer these queries?——————【线段树区间开方,区间求和】

    Can you answer these queries? Time Limit:2000MS     Memory Limit:65768KB     64bit IO Format:%I64d & ...

  2. HDU 4027 Can you answer these queries?(线段树区间开方)

    Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K ...

  3. HDU - 4027 Can you answer these queries?(线段树区间修改)

    https://cn.vjudge.net/problem/HDU-4027 题意 给一个有初始值的数组,存在两种操作,T=0时将[L,R]的值求平方根,T=1时查询[L,R]的和. 分析 显然不符合 ...

  4. HDU 4027 Can you answer these queries?(线段树的单点更新+区间查询)

    题目链接 题意 : 给你N个数,进行M次操作,0操作是将区间内的每一个数变成自己的平方根(整数),1操作是求区间和. 思路 :单点更新,区间查询,就是要注意在更新的时候要优化,要不然会超时,因为所有的 ...

  5. HDU 4027 Can you answer these queries【线段树】

    <题目链接> 题目大意: 给定一段序列,现在对指定区间进行两种操作:一是对指定区间进行修改,对其中的每个数字都开根号(开根号后的数字仍然取整):二是对指定区间进行查询,查询这段区间所有数字 ...

  6. HDU - 4027 Can you answer these queries?(线段树)

    给定一个长度为n的序列,m次操作. 每次操作 可以将一个区间内的所有数字变为它的根号. 可以查询一个区间内所有元素的和. 线段树的初级应用. 如果把一个区间内的元素都改为它的根号的话,是需要每个数字都 ...

  7. hdu 4027 Can you answer these queries?[线段树]

    题目 题意: 输入一个 :n  .(1<=n<<100000) 输入n个数    (num<2^63) 输入一个m :代表m个操作    (1<=m<<100 ...

  8. HDU 4027 Can you answer these queries(线段树 + 观察 )

    这题主要考察观察能力. 2^63最多只需要开7次根号就会变成1,当数字变成1之后就不需要再对其进行操作. 对于含有大于1数字的区间,向下更新. 对于数字全为1的区间,直接返回. #include &l ...

  9. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

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

随机推荐

  1. mysql索引优化及explain关键字段解释

    一.explain关键字解释 1.id MySQL QueryOptimizer 选定的执行计划中查询的序列号,表示查询中执行select 子句或操作表的顺序.id 值越大优先级越高,越先被执行.id ...

  2. mysql下突然丢失权限

    mysql  Can't read dir of  今天打开mysql数据库突然报了这个错误 查后发现是表没权限,进行了mysql的data目录权限修改 1.show global variables ...

  3. windows修改或删除已保存samba输入的用户名和密码

    可在系统的"控制面板\用户帐户\凭据管理器\windows 凭据"中找到 可以在"开始菜单->运行",输入"control userpasswo ...

  4. 如何通过EditPlus远程连接Linux

    1. File - FTP - FTP Settings 2. Add 3. 填写Linux的ip地址及用户名和密码 4. OK

  5. 错误 2 error C2059: 语法错误:“::”

    设置项目属性,在预定义处理器中添加定义NOMINMAX来禁止使用Vsual C++的min/max宏定义. 项目属性   ——> C/C++ ——> 预处理器 ——> 预处理器定义 ...

  6. IDEA设置maven项目的默认配置

    IDEA设置maven项目的默认配置 问题描述 很多刚使用idea的人,用其创建maven工程时会遇到一个问题,明明给项目设置了新的maven配置(使用阿里镜像源或者自定义maven版本),但是重新打 ...

  7. 转载 Python 安装setuptools和pip工具操作方法(必看)

    本文章转载自 脚本之家 http://www.jb51.net  感谢! setuptools模块和pip模块是python进行第三方库扩展的极重要工具,例如我们在需要安装一些爬虫或者数据分析的包时就 ...

  8. [code]彩色图像直方图均衡化 histogram_rgb

    //2013.9 eageldiao #ifdef HISTOGRAM_RGB unsigned ]; unsigned intncount[]={},ncount1[]={},ncount2[]={ ...

  9. docker tomcat启动慢

    镜像 https://hub.docker.com/r/errorlife/tomcat/ docker pull errorlife/tomcat

  10. C++ 静态绑定与动态绑定------绝不重新定义继承而来的缺省参数

    在了解静态绑定和动态绑定之前,先了解什么是对象的静态类型,什么是对象的动态类型. 对象的静态类型:对象在声明时采用的类型.是在编译器决定的. 对象的动态类型:目前所指对象的类型.是在运行期决定的. 动 ...