洛谷 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.本来我是看到区间这两个 ...
随机推荐
- git 删除github上的文件
硬盘删除文件后,执行$ git status 会提示你仍然需要$ git rm <文件> 此时如果是要删除大批量文件,这么一个一个命令下去不得累死人啊 其实可以这样(不管之前有 ...
- linux下创建用户(转)
转自 http://www.cnblogs.com/ylan2009/articles/2321177.html Note: 1, Linux Shell 按Tab键不能补全 发现使用新增的用户登陆的 ...
- python学习之getpass模块
getpass模块提供两个功能: getpass.getpass(prompt ='Password:',stream = None) 提示用户输入密码而不回显. 使用字符串提示提示用 ...
- HDU 1978 How many ways DP问题
How many ways Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- jQuery 时间戳转化成时间
//时间转换 function formatDate(now) { var now= new Date(now); var year=now.getFullYear(); ...
- linux内核开机logo显示调试
要使内核支持开机logo显示需要配置内核 配置如下: make menuconfig: Device Drivers ---> Graphics support ---> ...
- UVA 11732 "strcmp()" Anyone? (Trie)
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- java 关键字static
在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块. Java把内存分为栈内存和堆内存, 栈内存用来存放一些基本类型的变量.数组和对象的引用, 堆 ...
- oracle11g卸载,10g之类版本通用
鉴于oracle一些比较稀奇的问题,本人没碰到的不能帮忙解决的.而且比较着急赶时间的亲们,我就只能推荐先卸载在安装的办法了,这个方法一般用时也就1个小时到1个半小时之间,切记按步骤删除,别漏删了,不然 ...
- Bellman-Ford算法(有向图)
#include <iostream> #include <cstring> #include <cstdio> #define MAX 100 #define I ...