题解【SP2713】GSS4 - Can you answer these queries IV
题目描述
You are given a sequence \(A\) of \(N(N \leq 100,000)\) positive integers. There sum will be less than \(10^{18}\) . On this sequence you have to apply \(M (M \leq 100,000)\) operations:
(A) For given \(x\),\(y\), for each elements between the \(x-th\) and the \(y-th\) ones (inclusively, counting from \(1\)), modify it to its positive square root (rounded down to the nearest integer).
(B) For given \(x\),\(y\), query the sum of all the elements between the \(x-th\) and the \(y-th\) ones (inclusively, counting from \(1\)) in the sequence.
输入输出格式
输入格式
Multiple test cases, please proceed them one by one. Input terminates by \(EOF\).
For each test case:
The first line contains an integer \(N\). The following line contains \(N\) integers, representing the sequence \(A_{1}..A_{N}\).
The third line contains an integer \(M\). The next \(M\) lines contain the operations in the form i x y.
\(i=0\) denotes the modify operation, \(i=1\) denotes the query operation.
输出格式
For each test case:
Output the case number (counting from \(1\)) in the first line of output. Then for each query, print an integer as the problem required.
Print an blank line after each test case.
See the sample output for more details.
输入输出样例
输入样例#1
5
1 2 3 4 5
5
1 2 4
0 2 4
1 2 4
0 4 5
1 1 5
4
10 10 10 10
3
1 1 4
0 2 3
1 1 4
输出样例#1
Case #1:
9
4
6
Case #2:
40
26
题意翻译
「题意」: \(n\) 个数,和在\(10^{18}\) 范围内。
也就是\(\sum~a_i~\leq~10^{18}\)
现在有「两种」操作
0 x y把区间\([x,y]\) 内的每个数开方,下取整
1 x y询问区间\([x,y]\) 的每个数的和
「格式」: 有多组数据,数据以\(EOF\)结束,对于每组数据,输出数据的序号,每组数据之后输出一个空行。
「注意」: 不保证给出的区间\([x, y]\) 有\(x <= y\) ,如果\(x>y\) 请交换\(x\) ,\(y\)。
题解
\(SPOJ\)的\(GSS\)系列第四题。
乍一看和这题一模一样,于是准备直接拿一样的代码提交。
猛然发现:数据范围差了那么远!
这题中\(0 \leq n \leq 50000\),\(-2^{31} \leq others\)、\(ans \leq 2^{31} - 1\)。
而本题中\(n \leq 100000\),\(\sum~a_i~\leq~10^{18}\)直接提交一样的代码肯定会\(TLE\)。
于是尝试线段树。
普通操作与线段树大同小异,只是需要注意一个点:一个数已经小于或等于1就不要再开方了!
为什么呢?因为大于\(1\)的数开方会越来越接近\(1\),而小于\(1\)的数开方也会越来越接近\(1\),又因为\(\sqrt{1} = 1\),因此任何数经过开方操作都可以到\(1\)。
不难得出\(AC\)代码。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
using namespace std;
inline int gi()//快速读入
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
}
const int maxn = 100000 + 5;
int n, m, Case;
long long tr[maxn << 2], a[maxn], sq[maxn << 2];//tr为区间和,a为数字序列,sq为区间最大值
inline void pushup(int p)//上传节点
{
tr[p] = tr[p << 1] + tr[(p << 1) | 1];//增加区间和
sq[p] = max(sq[p << 1], sq[(p << 1) | 1]);//计算最大值
}
void build(int s, int t, int p)//建树
{
if (s == t)//已经是叶子节点
{
tr[p] = sq[p] = a[s];//初始化节点信息
return;//直接返回
}
int mid = (s + t) >> 1;//计算中点
build(s, mid, p << 1);//递归左子树
build(mid + 1, t, (p << 1) | 1);//递归右子树
pushup(p);//上传当前节点
}
void modify(int l, int r, int s, int t, int p)//进行区间开方操作
{
if (s == t)//已经到了叶子节点
{
tr[p] = sqrt(tr[p]);//进行开方
sq[p] = tr[p];//区间最大值就是当前数
return;//返回
}
int mid = (s + t) >> 1;//计算中间值
if (l <= mid && sq[p << 1] > 1) //如果目标节点在左区间且左区间最大值大于1
modify(l, r, s, mid, p << 1);//就递归左子树寻找目标节点
if (r > mid && sq[(p << 1) | 1] > 1) //目标节点在右区间且右区间最大值大于1
modify(l, r, mid + 1, t, (p << 1) | 1);//递归右子树寻找目标节点
pushup(p);//上传当前节点
}
long long getans(int l, int r, int s, int t, int p)//寻找答案
{
if (l <= s && r >= t)//当前区间包含于目标区间
{
return tr[p];//直接返回当前区间信息
}
long long sum = 0;//要返回的和
int mid = (s + t) >> 1;//计算中间值
if (l <= mid)//如果左端点在中点左侧
{
sum = sum + getans(l, r, s, mid, p << 1);//加上左区间的答案
}
if (r > mid)//如果右端点在中点右侧
{
sum = sum + getans(l, r, mid + 1, t, (p << 1) | 1);//加上右区间的答案
}
return sum;//返回答案
}
int main()
{
while (~scanf("%d", &n))//多组数据
{
printf("Case #%d:\n", ++Case);
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
memset(tr, 0, sizeof(tr));
memset(sq, 0, sizeof(sq));//多组数据要初始化
build(1, n, 1);//建树
m = gi();//输入询问个数
for (int i = 1; i <= m; i++)
{
int x = gi(), y = gi(), z = gi();
if (y > z) swap(y, z);//如果左端点大于右端点,就交换它们
if (x == 1)//是询问区间和
{
printf("%lld\n", getans(y, z, 1, n, 1));//输出答案
}
else
{
modify(y, z, 1, n, 1);//否则就进行区间开方
}
}
puts("");//一定记得数据之间要空行
}
return 0;//结束
}
题解【SP2713】GSS4 - Can you answer these queries IV的更多相关文章
- 线段树 SP2713 GSS4 - Can you answer these queries IV暨 【洛谷P4145】 上帝造题的七分钟2 / 花神游历各国
SP2713 GSS4 - Can you answer these queries IV 「题意」: n 个数,每个数在\(10^{18}\) 范围内. 现在有「两种」操作 0 x y把区间\([x ...
- SP2713 GSS4 - Can you answer these queries IV(线段树)
传送门 解题思路 大概就是一个数很少次数的开方会开到\(1\),而\(1\)开方还是\(1\),所以维护一个和,维护一个开方标记,维护一个区间是否全部为\(1/0\)的标记.然后每次修改时先看是否有全 ...
- 【SP2713 GSS4 - Can you answer these queries IV】 题解
题目链接:https://www.luogu.org/problemnew/show/SP2713 真暴力啊. 开方你开就是了,开上6次就都没了. #include <cmath> #in ...
- SP2713 GSS4 - Can you answer these queries IV
题目大意 \(n\) 个数,和在\(10^{18}\)范围内. 也就是\(\sum~a_i~\leq~10^{18}\) 现在有两种操作 0 x y 把区间[x,y]内的每个数开方,下取整 1 x y ...
- SP2713 GSS4 - Can you answer these queries IV 分块
问题描述 LG-SP2713 题解 分块,区间开根. 如果一块的最大值是 \(1\) ,那么这个块就不用开根了. 如果最大值不是 \(1\) ,直接暴力开就好了. \(\mathrm{Code}\) ...
- 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- GSS4 - Can you answer these queries IV(线段树懒操作)
GSS4 - Can you answer these queries IV(线段树懒操作) 标签: 线段树 题目链接 Description recursion有一个正整数序列a[n].现在recu ...
- GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 (线段树)
GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 GSS4 - Can you answer these qu ...
- 题解 SP2713 【GSS4 - Can you answer these queries IV】
用计算器算一算,就可以发现\(10^{18}\)的数,被开方\(6\)次后就变为了\(1\). 所以我们可以直接暴力的进行区间修改,若这个数已经到达\(1\),则以后就不再修改(因为\(1\)开方后还 ...
随机推荐
- 【python语法基础-经典练习题】python语法基础练习题01---商场打折
# 1.一家商场在降价促销.如果购买金额50-100元(包含50元和100元)之间,会给10%的折扣(打九折),# 如果购买金额大于100元会给20%折扣.编写一程序,询问购买价格,再显示出折扣(%1 ...
- XMind快捷键汇总
在 XMind: ZEN 中,快捷键是可以大大提高绘图效率的存在.掌握常用的快捷键组合,就可以在键盘上运指如飞,快速地进行思维导图的绘制.还在等什么?感兴趣的朋友,下面就和小编一起来看看吧! XMin ...
- 为什么MYSQL分页时使用limit+ order by会出现数据重复问题
问题描述: MYSQL采用limit进行翻页查询时,搭配order by ,在翻到第二页的时候可能会出现第一页的数据, 示例sql如下: select a,b from c where d = ' ...
- ip连接mysql时报不能连接
问题:springboot项目在用localhost连接mysql时没问题,但当localhost换成ip时出现 该问题:message from server: "Host 'DESKTO ...
- python3中的参数*args
python的传参是如何实现的 # 将未拆包的数据进行传参 def run(a,*args): #第一个参数传给了a print(a) # args是一个元组,里面是2和3两个参数 print(a ...
- 调用window Api 进行对特定窗口的进程ID进行操作
/// <summary> /// 获取窗口句柄 /// </summary> /// <param name="lpClassName">&l ...
- react-native构建基本页面4---渲染电影列表
电影列表 import React, { Component } from 'react' import { View, Image, Text, ActivityIndicator, FlatLis ...
- Error in nextTick: "TypeError: Cannot set property 'xxx' of undefined"解决办法
vue项目在控制台中报这个错误时,当看到nextTick词时想到vue的$nextTick()方法 Vue 在更新 DOM 时是异步执行的.只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件 ...
- hyper-v虚拟机不能访问外网的解决方案
直接说解决方案,将虚拟机的一张网卡改为旧版网络适配器即可.具体原因还不可知. 延申一下,一般应该使用的交换机,是“外部”类型即可.
- java类及实例初始化顺序
1.静态变量.静态代码块初始化顺序级别一致,谁在前,就先初始化谁.从上而下初始化(只在类加载时,初始化一次) 2.非静态变量.非静态代码块初始化顺序级别一致,谁在前,就先初始化谁.从上而下初始化(只要 ...