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. PAT甲级——A1077 Kuchiguse

    The Japanese language is notorious for its sentence ending particles. Personal preference of such pa ...

  2. 安装配置git服务

    创建git用户和组 groupadd -g git useradd -md /home/git -g -u git 安装依赖包 yum install curl-devel expat-devel g ...

  3. putty开源的ssh软件工具

    # 登录远程服务器需要ip和端口即可:还是开源工具用起来无忧无虑.无拘无束,这种感觉实在太舒服了,比起xshell开始免费.后来收费好太多太多,不用担心哪天过期了,想干嘛就干嘛. 软件下载地址:htt ...

  4. SSH协议的Python实现paramiko

    目录 paramiko安装 SSHClient类与SFTPClient类 SSHClient类的方法 SFTPClient类的方法 paramiko的基本使用 paramiko.SSHClient两种 ...

  5. Django项目:CMDB(服务器硬件资产自动采集系统)--06--06CMDB测试Linux系统采集硬件数据的命令01

    #base.py # ————————01CMDB获取服务器基本信息———————— from config import settings #配置文件 class BasePlugin(object ...

  6. OSGi.NET使用笔记

    一手资料来源于“开放工厂”,以下程序将会引用到一个核心文件UIShell.OSGi.dll 目前我对于OSGi这个框架的理解就是,主程序搜索并加载插件,以插件方式开放,便于扩展. 现在开始正式的旅程. ...

  7. 原 jeecms9自定义标签以及使用新创建的数据库表

    转载地址:https://blog.csdn.net/nice_meng/article/details/89179089 本系统使用的是jeecmsv9版本,收集网上知识后,进行个人汇总 首先,自己 ...

  8. sqlserver数据往别的数据库迁移

    背景:sqlserver数据库数据是服务于一个.net项目.后来由于去.net 要将数据前往高斯数据库 或者Oracle. 问题是 当sql Name Age Gender from student ...

  9. python-基础-面象对象

    1 类和对象 定义类 定义一个类,格式如下: class 类名: 方法列表 demo:定义一个Car类 # 定义类 class Car: # 方法 def getCarInfo(self): prin ...

  10. MyEclipse6.5安装SVN插件方法

    MyEclipse6.5安装SVN插件,掌握了几种方法,本节就像大家介绍一下MyEclipse6.5安装SVN插件的三种方法,看完本文你肯定有不少收获,希望本文能教会你更多东西. 一.安装方法: My ...