题目传送门

  

题目背景

XLk觉得《上帝造题的七分钟》不太过瘾,于是有了第二部。

题目描述

"第一分钟,X说,要有数列,于是便给定了一个正整数数列。

第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作。

第三分钟,k说,要能查询,于是便有了求一段数的和的操作。

第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围。

第五分钟,诗人说,要有韵律,于是便有了时间限制和内存限制。

第六分钟,和雪说,要省点事,于是便有了保证运算过程中及最终结果均不超过64位有符号整数类型的表示范围的限制。

第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。"

——《上帝造题的七分钟·第二部》

所以这个神圣的任务就交给你了。

输入输出格式

输入格式:

第一行一个整数 nn ,代表数列中数的个数。

第二行 nn 个正整数,表示初始状态下数列中的数。

第三行一个整数 mm ,表示有 mm 次操作。

接下来 mm 行每行三个整数k,l,r

  • k=0表示给 [l,r][l,r] 中的每个数开平方(下取整)
  • k=1表示询问 [l,r][l,r] 中各个数的和。

数据中有可能 l>rl>r ,所以遇到这种情况请交换l和r。

输出格式:

对于询问操作,每行输出一个回答。

输入输出样例

输入样例#1: 复制

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
输出样例#1: 复制

19
7
6

说明

对于30%的数据,1≤n,m≤1000,数列中的数不超过32767。

对于100%的数据,1≤n,m≤100000,1≤l,r≤n,数列中的数大于0,且不超过10^12。

注意l有可能大于r,遇到这种情况请交换l,r。


  分析:首先,要求进行区间修改和区间查询,很明显的线段树啊。这题用线段树确实也可以做,但是开方是不支持区间操作的,所以只能单点修改,但是会发现单点修改最多只能进行6次,那么就打标记,直接暴力单点修改就可以A了。

  但是这题还可以用树状数组套并查集做,而且更优。因为树状数组是用于保存前缀和的,那么每一次修改只要修改前缀和即可,每次的操作复杂度为O(logn),查询也一样。那么修改操作和线段树也差不多。每次单点修改,最多只有6次,但是这样复杂度还是O(n^2),那么并查集的作用就显现出来了。每次修改过以后,如果该点的值已经<=1了,那么就将该点的fa[i]修改为i+1,修改的for循环就可以这样写:

  for(int i=find(l);i<=r;i=find(i+1))

  就可以直接跳过不需要修改的点,优化复杂度了,平摊下来复杂度大约也就是树状数组的复杂度O(nlogn)。

  Code:

#include<bits/stdc++.h>
#define Fi(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
using namespace std;
typedef long long ll;
const int N=1e5+;
ll a[N],c[N];int n,m,fa[N];
inline ll read()
{
char ch=getchar();ll num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
}
inline int find(int x){return (fa[x]==x||!fa[x])?fa[x]=x:fa[x]=find(fa[x]);}
inline void update(int x,ll y){for(;x<=n;x+=x&-x)c[x]+=y;}
inline ll get(int x){ll ret=;for(;x;x-=x&-x)ret+=c[x];return ret;}
inline void change(int l,int r)
{
for(int i=find(l);i<=r;i=find(i+)){
ll temp=(ll)sqrt(a[i]);update(i,temp-a[i]);
a[i]=temp;if(a[i]<=)fa[i]=find(i+);}
}
int main()
{
n=read();Fi(i,,n){a[i]=read();update(i,a[i]);fa[i]=i;if(a[i]<=)fa[i]=i+;}
m=read();ll x,y,z;Fi(i,,m){x=read();y=read();z=read();if(y>z)swap(y,z);
if(x==)change(y,z);else printf("%lld\n",get(z)-get(y-));}return ;
}

洛谷P4145 上帝造题的七分钟2/花神游历各国 [树状数组,并查集]的更多相关文章

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

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

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

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

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

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

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

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

  5. P4145 上帝造题的七分钟2 / 花神游历各国(线段树区间开平方)

    有点意思,不需要什么懒标记之类的东西,因为一个数无论怎样开平方,最后取整的结果必然会是1,所以我们不妨用最大值来维护,若区间最大值不为1,就暴力修改,否则不用管. #include<bits/s ...

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

    思路 每个数不会被开方超过log次,对每个数暴力开方即可 代码 #include <algorithm> #include <cstring> #include <cst ...

  7. luogu P4145 上帝造题的七分钟2 / 花神游历各国 维护区间和&&区间开根号

    因为开根号能使数字减小得非常快 所以开不了几次(6次?)很大的数就会变成1..... 所以我们可以维护区间最大值,若最大值>1,则继续递归子树,暴力修改叶节点,否则直接return (好像也可以 ...

  8. day1 晚上 P4145 上帝造题的七分钟2 / 花神游历各国 线段树

    #include<iostream> #include<cstdio> #include<cmath> using namespace std; ; struct ...

  9. [Luogu P4145] 上帝造题的七分钟2 / 花神游历各国

    题目链接 题目简要:我们需要一个能支持区间内每一个数开方以及区间求和的数据结构. 解题思路:说道区间修改区间查询,第一个想到的当然就是分块线段树.数据范围要用long long.本来我是看到区间这两个 ...

随机推荐

  1. table第一行合并,其余行宽度失效问题

    <col>标签 http://www.w3school.com.cn/tags/tag_col.asp 由于表格中有一行合并过,所以其它没有合并的行的列宽就会平均化,对列宽的设置也会失效. ...

  2. 数据结构&图论:图

    在这里对图的存储和遍历进行一个规范,为以后更复杂的数据结构学习打下基础 首先是邻接矩阵的形式,适合于存稠密图,如果是全连接图就再合适不过了 int a[maxn][maxn]; 一个二维数组就可以搞定 ...

  3. vijos 1313 金明的预算方案 树形DP

    描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今天一 ...

  4. MyBatis框架的使用及源码分析(五) DefaultSqlSessionFactory和DefaultSqlSession

    我们回顾<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 一文的示例 private static SqlSessionFactory getSessionF ...

  5. [uva11997]k个最小和

    一个k*k的矩阵,每行选取一个数相加则得到一个和,求最小的前k个和. k<=750 已知前m行最小的前k个和d[1]…d[k],则前m+1行最小的前k个和都必定是d[i](i<=k)+a[ ...

  6. 【BZOJ3884】上帝与集合的正确用法 [欧拉定理]

    上帝与集合的正确用法 Time Limit: 5 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Input 第一行一个T ...

  7. python学习笔记(五)数值类型和类型转换

    Python中的数值类型有: 整型,如2,520 浮点型,如3.14159,1.5e10 布尔类型 True和False e记法: e记法即对应数学中的科学记数法 >>> 1.5e1 ...

  8. Linux 入门记录:九、Linux 文件系统挂载管理

    一.挂载操作 磁盘或分区创建好文件系统后,需要挂载到一个目录才能够使用. Windows 或 Mac 系统会进行自动挂载,一旦创建好文件系统后会自动挂载到系统上,Windows 上称之为 C 盘.D ...

  9. MHA切换过程:

    1.监测master的状态Ping(SELECT) succeeded, waiting until MySQL doesn't respond.. 2.当监控发现master异常时发出warning ...

  10. 【模板】BZOJ 3685: 普通van Emde Boas树——Treap

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3685 据说神犇都是用zkw线段树水过的啊... 我蒟蒻只会写treap,加了fread之后8 ...