题目链接


题解

题目大意

一个序列,支持区间开方与求和操作。

算法:线段树实现开方修改与区间求和

分析

  • 显然,这道题的求和操作可以用线段树来维护
  • 但是如何来实现区间开方呢
  • 大家有没有这样的经历:玩计算器的时候,把一个数疯狂的按开方,最后总会变成 \(1\),之后在怎样开方也是 \(1\) (\(\sqrt1=1\))
  • 同样的,\(\sqrt0=0\)
  • 所以,只要一段区间里的所有数全都 \(\leq 1\) 了,便可以不去修改它

实现

  • 线段树维护区间和 \(sum\) 与最大值 \(Max\)
  • 在修改过程中,只去修改 \(Max > 1\) 的区间
  • 到了叶子节点对\(sum\)和\(Max\)进行开方就行了

复杂度

  • 每个数 \(\leq 10 ^ {12}\),所以至多开方\(6\)次便可以得到\(1\)
  • 每次操作是 \(\log n\)的,总复杂度\(O(n \log n)\)

注意事项

  • 请使用long long
  • 可能 \(l > r\)(把我坑了)

代码:

#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstdio> using namespace std;
typedef long long LL;
const int MAXN = 100100; int n, m;
int cnt;
LL a[MAXN];
struct node
{
int left, right;
LL s, Max;
node *ch[2];
}pool[MAXN << 2], *root; inline void pushup(node *r)
{
r->s = r->ch[0]->s + r->ch[1]->s;
r->Max = max(r->ch[0]->Max, r->ch[1]->Max);
} inline void Build_Tree(node *r, int left, int right)
{
r->left = left;
r->right = right;
if(left == right)
{
r->s = r->Max = a[left];
return ;
}
int mid = (left + right) / 2;
node *lson = &pool[++cnt];
node *rson = &pool[++cnt];
r->ch[0] = lson;
r->ch[1] = rson;
Build_Tree(lson, left, mid);
Build_Tree(rson, mid + 1, right);
pushup(r);
} inline void change(node *r, int left, int right)
{
if(r->left == r->right)
{
r->s = sqrt(r->s);
r->Max = sqrt(r->Max);
return ;
} int mid = (r->left +r-> right) / 2;
if(left <= mid && r->ch[0]->Max > 1) change(r->ch[0], left, right);
if(mid < right && r->ch[1]->Max > 1) change(r->ch[1], left, right);
pushup(r);
} inline LL query(node *r, int left, int right)
{
if(r->left == left && r->right == right)
return r->s;
if(r->ch[0]->right >= right) return query(r->ch[0], left, right);
else if(r->ch[1]->left <= left) return query(r->ch[1], left, right);
else
return query(r->ch[0], left, r->ch[0]->right) +
query(r->ch[1], r->ch[1]->left, right);
}
int main()
{
scanf("%d", &n);
root = &pool[0];
for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
scanf("%d", &m);
Build_Tree(root, 1, n);
for(int i = 1; i <= m; i++)
{
int opt, l, r;
scanf("%d%d%d", &opt, &l, &r);
if(l > r) swap(l, r);
if(opt) printf("%lld\n", query(root, l, r));
else change(root, l, r);
}
return 0;
}

题解【luoguP4145 上帝造题的七分钟2(花神游历各国)】的更多相关文章

  1. 题解 洛谷 P4145 【上帝造题的七分钟2 / 花神游历各国】

    题目 上帝造题的七分钟2 / 花神游历各国 题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. ...

  2. GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 (线段树)

    GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 GSS4 - Can you answer these qu ...

  3. 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)

    题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...

  4. 洛谷P4145 上帝造题的七分钟2/花神游历各国 [树状数组,并查集]

    题目传送门 题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是 ...

  5. [bzoj3038/3211]上帝造题的七分钟2/花神游历各国_线段树

    上帝造题的七分钟2 bzoj-3038 题目大意:给定一个序列,支持:区间开方:查询区间和. 注释:$1\le n\le 10^5$,$1\le val[i] \le 10^{12}$. 想法:这题还 ...

  6. 洛谷P4145——上帝造题的七分钟2 / 花神游历各国

    题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...

  7. 【luogu4145】上帝造题的七分钟2 / 花神游历各国--区间开根-线段树

    题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...

  8. 【题解】 Luogu P4145 上帝造题的七分钟2 / 花神游历各国

    原题传送门 这道题实际和GSS4是一样的,只是输入方式有点区别 GSS4传送门 这道题暴力就能过qaq(这里暴力指线段树) 数据比较水 开方修改在线段树中枚举叶节点sqrt 查询区间和线段树基本操作 ...

  9. 线段树 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 ...

  10. 洛谷 P4145 上帝造题的七分钟2 / 花神游历各国

    洛谷 这题就是区间开根号,区间求和.我们可以分块做. 我们记布尔数组vis[i]表示第i块中元素是否全部为1. 因为显然当一个块中元素全部为1时,并不需要对它进行根号操作. 我们每个块暴力开根号,因为 ...

随机推荐

  1. OpenMPI源码剖析1:MPI_Init初探

    OpenMPI的底层实现: 我们知道,OpenMPI应用起来还是比较简单的,但是如果让我自己来实现一个MPI的并行计算,你会怎么设计呢?————这就涉及到比较底层的东西了. 回想起我们最简单的代码,通 ...

  2. HDU 2494/POJ 3930 Elevator(模拟)(2008 Asia Regional Beijing)

    Description Too worrying about the house price bubble, poor Mike sold his house and rent an apartmen ...

  3. ZOJ 3686 A Simple Tree Problem(线段树)

    Description Given a rooted tree, each node has a boolean (0 or 1) labeled on it. Initially, all the ...

  4. 每周psp-第五周

    PSP表格: 类别 任务 开始时间 结束时间 中断时间 delta时间 开会 scrum立会 10.13下午6:04 10.13下午6:34 0 30 开会 scrum立会 10.14下午6:02 1 ...

  5. 软件功能-东北师大站-第三次作业(PSP)

    1.本周PSP 2.本周进度条 3.本周累计进度图 代码累计折线图 博文字数累计折线图 本周PSP饼状图

  6. laravel开发环境部署遇到的问题和个人感受

    >感受 用chrome浏览器 英语很重要 跟上更新的步伐 要不断学习 问问题要把问题描述清楚,先尝试解决,解决不了再问大佬 情绪要稳定,不能因为一个问题困扰两天就想放弃了 发现了 stack o ...

  7. LintCode-54.转换字符串到整数

    转换字符串到整数 实现atoi这个函数,将一个字符串转换为整数.如果没有合法的整数,返回0.如果整数超出了32位整数的范围,返回INT_MAX(2147483647)如果是正整数,或者INT_MIN( ...

  8. iOS-修改导航栏文字字体和颜色

    //修改导航栏文字字体和颜色 nav.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[RGBColor co ...

  9. python中装饰器的原理以及实现,

    python版本 3.6 1.python的装饰器说白了就是闭包函数的一种应用场景,在运用的时候我们遵循 #开放封闭原则:对修改封闭,对拓展开放 2.什么是装饰器 #装饰他人的器具,本身可以是任意可调 ...

  10. Python使用ElementTree美化XML格式

    Python中使用ElementTree可以很方便的处理XML,但是产生的XML文件内容会合并在一行,难以看清楚. 如下格式: <root><aa>aatext<cc&g ...