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补充( 查询)

    show create table 表名 \G;(查看创建的属性) alter table 表名 auto_increment=xx;(修改自增起始值) set session auto_increm ...

  2. history配置

    /etc/profile配置文件中,末尾增加如下参数项: HFILE=`who -m | awk '{print $1}'`readonly HISTFILE=/var/history/$HFILE- ...

  3. pandas一些基本操作(DataFram和Series)_2

    import numpy as nparr1 = np.arange(32).reshape(8,4)print(arr1)arr1 = arr1.reshape(-1);print(arr1)arr ...

  4. hihocoder 1084 (哈希)

    题目链接 时间限制:4000ms 单点时限:4000ms 内存限制:256MB 描述 你知道KMP吗?它是用于判断一个字符串是否是另一个字符串的子串的算法.今天我们想去扩展它. 在信息理论中,在两个相 ...

  5. DVWA 之medium级别sql注入

    中级注入的提交方式从get请求改为post请求,可以用burp抓包注入或抓注入点 1 .  判断是否有注入 sqlmap -u "http://192.168.242.1/dvw/vulne ...

  6. MySql存储过程批量删除多个数据库中同名表中的指定字段

    1. 创建存储过程batchDeleteField:删除所有名称为"MyDB_"开头的数据库中的指定字段 -- ---------------------------- -- Pr ...

  7. 【DM642学习笔记九】XDS560仿真器 Can't Initialize Target CPU

    以前用的瑞泰的ICETEK-5100USB仿真器,现在换成XDS560试了试,速度快多了.把720*576的图片在imgae中显示也只需要四五秒钟.而5100仿真器需要三四分钟. 仿真器驱动安好后,刚 ...

  8. MySQL数据库基本使用

    一 .数据库概述 数据库就是以一定格式进行组织的数据的集合.通俗来看数据库就是用户计算机上 一些具有特殊格式的数据文件的集合. 数据库也可以理解为表格,大家都知道表格都是由表名.表头.数据等几部分组成 ...

  9. Eureka 客户端连接Eureka服务端时 报Cannot execute request on any known server 解决办法

    报Cannot execute request on any known server 这个错,总的来说就是连接Eureka服务端地址不对. 因为配置eureka.client.serviceUrl. ...

  10. mavenjar 一些拉取不下来问题

    http://search.maven.org/这里找相近版本替换试试.拉取不下来是因为官方版本不足或者网络问题.