洛谷 P4145 上帝造题的七分钟2 / 花神游历各国
这题就是区间开根号,区间求和。我们可以分块做。
我们记布尔数组vis[i]表示第i块中元素是否全部为1。
因为显然当一个块中元素全部为1时,并不需要对它进行根号操作。
我们每个块暴力开根号,因为数字最大\(2^{31}\),所以最多每个数字开几次根号,所以时间复杂度很低。
记录sum[i]表示第i块的总和,所以我们得到这样的算法:
当出现修改操作时,我们暴力修改,如果vis[i]为真,则不对该块进行操作。
而出现查询操作时,直接对正常操作再输出即可。
代码略丑:
#include <bits/stdc++.h>
#define _ putchar('\n')
using namespace std;
typedef int _int;
#define int long long
const int N=100010;
bool vis[N];
int n,m,a[N],len,num;
int pos[N],sum[N],ll[N],rr[N];
inline void read(int &aa)
{
aa=0;char c=getchar();
for (;c>'9'||c<'0';c=getchar());
for (;c>='0'&&c<='9';c=getchar())
aa=(aa<<3)+(aa<<1)+(c^48);
}
char buffer[N],*S,*T;
inline char Get_Char()
{
if (S==T) {
T=(S=buffer)+fread(buffer,1,N,stdin);
if (S==T) return EOF;
}
return *S++;
}
int Get_Int()
{
char c;
int re=0;
for (c=Get_Char();c<'0'||c>'9';c=Get_Char());
while (c>='0'&&c<='9')
re=(re<<1)+(re<<3)+(c-'0'),c=Get_Char();
return re;
}
void print(int x)
{
if (x>9) print(x/10);putchar(x%10^48);
}
void build()
{
len=sqrt(n);
num=n/len;if (n%len) ++num;
for (int i=1;i<=num;++i)
ll[i]=(i-1)*len+1,rr[i]=i*len;
rr[num]=n;
for (int i=1;i<=num;++i)
for (int j=ll[i];j<=rr[i];++j)
sum[i]+=a[j];
for (int i=1;i<=n;++i)
pos[i]=(i-1)/len+1;
}
int ask(int l,int r)
{
int ans=0;
if (pos[l]==pos[r]) {
for (int i=l;i<=r;++i)
ans+=a[i];
return ans;
}
for (int i=l;i<=rr[pos[l]];++i)
ans+=a[i];
for (int i=pos[l]+1;i<pos[r];++i)
ans+=sum[i];
for (int i=ll[pos[r]];i<=r;++i)
ans+=a[i];
return ans;
}
void change(int l,int r)
{
if (pos[l]==pos[r]) {
if (vis[pos[l]]) return;
for (int i=l;i<=r;++i) {
sum[pos[l]]-=a[i];
a[i]=sqrt(a[i]);
sum[pos[l]]+=a[i];
}
vis[pos[l]]=1;
for (int i=ll[pos[l]];i<=rr[pos[l]];++i)
if (a[i]>1) {vis[pos[l]]=0;break;}
return;
}
if (!vis[pos[l]]) {
for (int i=l;i<=rr[pos[l]];++i) {
sum[pos[l]]-=a[i];
a[i]=sqrt(a[i]);
sum[pos[l]]+=a[i];
}
vis[pos[l]]=1;
for (int i=ll[pos[l]];i<=rr[pos[l]];++i)
if (a[i]>1) {vis[pos[l]]=0;break;}
}
if (!vis[pos[r]]) {
for (int i=ll[pos[r]];i<=r;++i) {
sum[pos[r]]-=a[i];
a[i]=sqrt(a[i]);
sum[pos[r]]+=a[i];
}
vis[pos[r]]=1;
for (int i=ll[pos[r]];i<=rr[pos[r]];++i)
if (a[i]>1) {vis[pos[r]]=0;break;}
}
for (int i=pos[l]+1;i<pos[r];++i) {
if (vis[i]) continue;
for (int j=ll[i];j<=rr[i];++j) {
sum[i]-=a[j];
a[j]=sqrt(a[j]);
sum[i]+=a[j];
}
vis[i]=1;
for (int j=ll[i];j<=rr[i];++j)
if (a[j]>1) {vis[i]=0;break;}
}
}
_int main()
{
n=Get_Int();
for (int i=1;i<=n;++i) a[i]=Get_Int();
build();
m=Get_Int();
int opt,l,r;
while (m--) {
opt=Get_Int(),l=Get_Int(),r=Get_Int();
if (l>r) swap(l,r);
if (opt) print(ask(l,r)),_;
else change(l,r);
}
return 0;
}
洛谷 P4145 上帝造题的七分钟2 / 花神游历各国的更多相关文章
- 洛谷P4145 上帝造题的七分钟2/花神游历各国 [树状数组,并查集]
题目传送门 题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是 ...
- 洛谷P4145——上帝造题的七分钟2 / 花神游历各国
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- 【题解】 Luogu P4145 上帝造题的七分钟2 / 花神游历各国
原题传送门 这道题实际和GSS4是一样的,只是输入方式有点区别 GSS4传送门 这道题暴力就能过qaq(这里暴力指线段树) 数据比较水 开方修改在线段树中枚举叶节点sqrt 查询区间和线段树基本操作 ...
- P4145 上帝造题的七分钟2 / 花神游历各国(线段树区间开平方)
有点意思,不需要什么懒标记之类的东西,因为一个数无论怎样开平方,最后取整的结果必然会是1,所以我们不妨用最大值来维护,若区间最大值不为1,就暴力修改,否则不用管. #include<bits/s ...
- P4145 上帝造题的七分钟2 / 花神游历各国
思路 每个数不会被开方超过log次,对每个数暴力开方即可 代码 #include <algorithm> #include <cstring> #include <cst ...
- luogu P4145 上帝造题的七分钟2 / 花神游历各国 维护区间和&&区间开根号
因为开根号能使数字减小得非常快 所以开不了几次(6次?)很大的数就会变成1..... 所以我们可以维护区间最大值,若最大值>1,则继续递归子树,暴力修改叶节点,否则直接return (好像也可以 ...
- day1 晚上 P4145 上帝造题的七分钟2 / 花神游历各国 线段树
#include<iostream> #include<cstdio> #include<cmath> using namespace std; ; struct ...
- [Luogu P4145] 上帝造题的七分钟2 / 花神游历各国
题目链接 题目简要:我们需要一个能支持区间内每一个数开方以及区间求和的数据结构. 解题思路:说道区间修改区间查询,第一个想到的当然就是分块线段树.数据范围要用long long.本来我是看到区间这两个 ...
随机推荐
- 封面式 code-代码助手
1 保存代码 2 搜索代码 3 生成网页 下载地址: http://gudianxiaoshuo.com
- 解决eclipse偶尔无视breakpoint的行为
一般是如果你使用了T[]这样的参数列表,也就是generic array作为参数,你就算给函数打了断点,有时也会被eclipse无视 比如如下代码,你在调试main的时候,eclipse就会把doPa ...
- PHP学习笔记(3)GD库画图
<?php //加header头,不然浏览器乱码 header("content-type: image/png"); //创建画布资源 $img = imagecreate ...
- 在Linux系统上查看Apache服务器的错误日志
错误日志和访问日志文件为系统管理员提供了有用的信息,比如,为 Web 服务器排障,保护系统不受各种各样的恶意活动侵犯,或者只是进行各种各样的分析以监控 HTTP 服务器.根据你 Web 服务器配置的不 ...
- CentOS装JDK1.8
1.下载jdk1.8:http://download.csdn.net/download/yichen01010/10017267 直接使用liunx下默认安装的浏览器 下载 2.卸载系统自带的jdk ...
- 邮件正文及其附件的发送的C++实现
这段代码我花了整整一天来编写,假设转载,请注明出处,谢谢! 前面的一篇文章已经讲了怎样发送邮件正文,原理我就不再叙述了.要了解的同学请到这里查看! http://blog.csdn.ne ...
- js Date操作
new Date(new Date().getTime() - 24 * 24 * 60 * 60 * 1000)类似C#中的AddDays,返回一个月前的时间 //时间格式化方法 v ...
- Canvas清屏的实现
/** * Canvas清屏的操作 * * 參考资料: http://blog.csdn.net/lfdfhl/article/details/9076001 * */ private void cl ...
- unity 打开文件夹并鼠标选中某文件
System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.FileName = "explor ...
- C# 文件读写操作整理
http://www.cnblogs.com/wangshenhe/archive/2012/05/09/2490438.html