LibreOJ 6281 数列分块入门5
题目链接:https://loj.ac/problem/6281
参考博客:https://blog.csdn.net/qq_36038511/article/details/79725027
我一开始看到开方有点懵,看了上面的博客说2^31差不多5次开方就快变成1了,可以开标记数组,于是按照这个思路写了下,然后就过了,看来以后还要多看题意分析数据。
代码:
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 50010
int n,m,k,t,block;
int a[maxn],tag[maxn],sum[maxn],vis[maxn],lump[maxn];
void kaif(int l,int r)//把l到r之间的数字开方
{
for(int i=l;i<=min(lump[l]*block,r);i++)//直接改左边的不完整区间,同时该区间和
{
sum[lump[l]]-=a[i];
a[i]=sqrt(a[i]);
sum[lump[l]]+=a[i];
}
if(lump[l]!=lump[r])
{
for(int i=(lump[r]-)*block+;i<=r;i++)
{
sum[lump[r]]-=a[i];
a[i]=sqrt(a[i]);
sum[lump[r]]+=a[i];
}
}
for(int i=lump[l]+;i<=lump[r]-;i++)//记录这个区间开方了多少次
{
tag[i]++;
}
}
int cal(int x,int num)//求数字x开方num次得出的结果
{
while(num--&&x>)
{
x=sqrt(x);
}
return x;
}
int get_sum(int l,int r)//求区间和
{
int ans=;
for(int i=l;i<=min(lump[l]*block,r);i++)//左区间暴力求和
{
ans+=cal(a[i],tag[lump[l]]);
}
if(lump[l]!=lump[r])
{
for(int i=(lump[r]-)*block+;i<=r;i++)//右区间
{
ans+=cal(a[i],tag[lump[r]]);
}
}
for(int i=lump[l]+;i<=lump[r]-;i++)
{
if(!vis[i])//如果vis[i]==0,表示区间i还有大于1的数字
{
int flag=;//标记看开方之后是否还有大于1的数字
sum[i]=;//区间和清空
for(int j=(i-)*block+;j<=i*block;j++)
{
a[j]=cal(a[j],tag[i]);
sum[i]+=a[j];//重新计算区间和
if(a[j]>)//只要有一个大于1
flag=;
}
tag[i]=;//区间未开方数字清零
if(!flag)
vis[i]=;
}
ans+=sum[i];
}
return ans;
}
int main()
{
scanf("%d",&n);
block=sqrt(n);
fill(sum,sum+maxn-,);
fill(tag,tag+maxn-,);
fill(vis,vis+maxn-,);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
lump[i]=(i-)/block+;
sum[lump[i]]+=a[i];
}
for(int i=;i<=n;i++)
{
int op,l,r,w;
scanf("%d%d%d%d",&op,&l,&r,&w);
if(op==)
kaif(l,r);
else
printf("%d\n",get_sum(l,r));
}
return ;
}
LibreOJ 6281 数列分块入门5的更多相关文章
- LibreOJ 6281 数列分块入门 5(分块区间开方区间求和)
题解:区间开方emmm,这马上让我想起了当时写线段树的时候,很显然,对于一个在2^31次方以内的数,开方7-8次就差不多变成一了,所以我们对于每次开方,如果块中的所有数都为一了,那么开方也没有必要了. ...
- LOJ #6281. 数列分块入门 5-分块(区间开方、区间求和)
#6281. 数列分块入门 5 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 5 题目描述 给出 ...
- LibreOJ 6277. 数列分块入门 1 题解
题目链接:https://loj.ac/problem/6277 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 \( ...
- LOJ 6281 数列分块入门 5
简化版题意 给出一个长为n的数列,以及n个操作,操作涉及区间开方(每个数都向下取整),区间求和,保证所有数都为有符号32位正整数. N<=50000 Solution 首先我们先思考: 一个有符 ...
- LibreOJ 6277 数列分块入门 1(分块)
题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...
- [Libre 6281] 数列分块入门 5 (分块)
水一道入门分块qwq 题面:传送门 开方基本暴力.. 如果某一个区间全部都开成1或0就打上标记全部跳过就行了 因为一个数开上个四五六次就是1了所以复杂度能过233~ code: //By Menteu ...
- LibreOJ 6278. 数列分块入门 2 题解
题目链接:https://loj.ac/problem/6278 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的元素个数. ...
- LibreOJ 6285. 数列分块入门 9
题目链接:https://loj.ac/problem/6285 其实一看到是离线,我就想用莫队算法来做,对所有询问进行分块,但是左右边界移动的时候,不会同时更新数字最多的数,只是后面线性的扫了一遍, ...
- LibreOJ 6282. 数列分块入门 6
题目链接:https://loj.ac/problem/6282 参考博客:http://www.cnblogs.com/stxy-ferryman/p/8560551.html 这里如果用数组的话元 ...
随机推荐
- ARP 欺骗攻击与防御
<一> ARP攻防 理论 和 工具 工具: 01: Wireshark ( 抓包软件 ) 02: P2P终结者 ( ARP欺骗工具 ) 03: cain & abel ( ...
- 09-清除默认格式 reset.css
根据需要选择和裁剪后使用,以减少代码量 /* 清除内外边距 */ body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elem ...
- Java中,&&与&,||与|的区别
在java的逻辑运算符中,有这么四类:&&(短路与),&,|,||(短路或). &&和&都是表示与,区别是&&只要第一个条件不满足,后面 ...
- 集合,ArrayList
用集合代替数组: Console.Write("请输入人数:"); int renshu = int.Parse(Console.ReadLine()); ArrayList ch ...
- springmvc配置接口返回的数据是json
首先要导入所需要的jar,使用maven方式管理jar包 <!-- 配置接口返回数据json --> <dependency> <groupId>com.faste ...
- Socket buffer 调优相关
http://www.man7.org/linux/man-pages/man7/tcp.7.html The maximum sizes for socket buffers declared vi ...
- MySQL null与not null和null与空值''的区别
参考连接:https://segmentfault.com/a/1190000009540449 相信很多用了MySQL很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问: 我字段类型是n ...
- English: How to Pronounce R [ɹ] Consonant
English: How to Pronounce R [ɹ] Consonant Share Tweet Share Tagged With: Most Popular, Sound How-To ...
- nginx的websock问题解决
生产环境中有一个项目需要使用到websock,但是项目上线后发现websock连接后马上断开,但是在测试环境没有问题,后来就想到配置文件和nginx版本问题 核对后发现,nginx和配置文件都是相同的 ...
- .NET 基础知识
.net程序基本编写.执行流程(c#) 1>编写c#代码,保存为.cs文件. 2>通过csc.exe程序来将.cs文件编译为.net程序集(.exe或.dll).此 ...