题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=5177

  在网上看到的题解基本都是用主席树,也就是带点骚操作的暴力直接艹过去的。这里分享一个比较清真的分块做法。

  因为$ p , a_i $的值域较小,因此我们可以考虑把序列分成$ size $块,预处理出每个块内的数模每个$ p $的最大值,那么查询时只需查询区间中的整块答案,然后再统计零散的元素的贡献。预处理时,我们可以考虑对当前块维护一个数组$ last[i] $表示在当前块内出现过的小于等于$ i $的最大的数,在计算模$ p $的答案时,因为$ f(x)=x \mod p $是一个分段的单调函数,在$ [kp,(k+1)p-1] (k \in \mathbb{Z})$上单调递增,因此我们只需对每个区间$ [kp,(k+1)p-1] $求出区间内的最大值,也就是$ last[(k+1)p-1] $,作为模$ p $值最大的数。因此,每个块的预处理复杂度为$ O(1000 \ln 1000) $。

  总时间复杂度为$ O(n+1000 \ln 1000size+m(size+\frac{n}{size})) $,当取$ size=\sqrt{n} $时时间复杂度为$ 1000 \ln 1000 \sqrt{n}+m\sqrt{n}) \approx 5.7 \times 10^7 $,比那些$ O(1000 m \log n) $的做法清真到不知道哪里去了。

  代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<set>
#define ll long long
#define mod 1000000007
#define Mod1(x) (x>=mod?x-mod:x)
#define Mod2(x) (x<0?x+mod:x)
#define maxn 1000010
inline ll read()
{
ll x=; char c=getchar(),f=;
for(;c<''||''<c;c=getchar())if(c=='-')f=-;
for(;''<=c&&c<='';c=getchar())x=x*+c-'';
return x*f;
}
inline void write(ll x)
{
static int buf[],len; len=;
if(x<)x=-x,putchar('-');
for(;x;x/=)buf[len++]=x%;
if(!len)putchar('');
else while(len)putchar(buf[--len]+'');
}
inline void writeln(ll x){write(x); putchar('\n');}
inline void writesp(ll x){write(x); putchar(' ');}
int mx[][],last[];
int a[maxn];
int n,m,size;
int main()
{
// freopen("bzoj5177.in","r",stdin);
// freopen("bzoj5177.out","w",stdout);
n=read(); m=read();
for(int i=;i<n;i++)
a[i]=read();
size=sqrt(n);
// writeln(size);
for(int k=;k*size<n;k++){
memset(last,,sizeof(last));
for(int i=k*size;i<(k+)*size&&i<n;i++)
last[a[i]]=a[i];
for(int i=;i<=;i++)
if(!last[i])last[i]=last[i-];
for(int i=;i<=;i++){
for(int j=i;j<=;j+=i)
mx[k][i]=std::max(mx[k][i],last[j-]-(j-i));
mx[k][i]=std::max(mx[k][i],last[]%i);
}
}
while(m--){
int l=read(),r=read(),p=read();
if(l>r){
int tmp=l; l=r; r=tmp;
}
int idl=l/size,idr=r/size;
if(idl==idr){
int ans=;
for(int i=l;i<=r;i++)
ans=std::max(ans,a[i]%p);
writeln(ans);
}
else{
int ans=;
for(int i=idl+;i<idr;i++)
ans=std::max(ans,mx[i][p]);
for(int i=l;i<(idl+)*size;i++)
ans=std::max(ans,a[i]%p);
for(int i=idr*size;i<=r;i++)
ans=std::max(ans,a[i]%p);
writeln(ans);
}
}
// fclose(stdin); fclose(stdout);
return ;
}

bzoj5177

【bzoj5177】[Jsoi2013]贪心的导游(分块)的更多相关文章

  1. [Bzoj5177][Jsoi2013]贪心的导游(主席树)

    5177: [Jsoi2013]贪心的导游 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 32  Solved: 15[Submit][Status] ...

  2. BZOJ5177 : [Jsoi2013]贪心的导游

    首先预处理出对于每个模数,所有被模数按结果从大到小排序的结果,那么对于一个询问,如果可以在$O(1)$时间内判断某个数字是否出现,则可以$O(1000)$回答. 考虑对序列进行分治,对于区间$[l,r ...

  3. 「JSOI2013」贪心的导游

    「JSOI2013」贪心的导游 传送门 多次询问区间内%一个数的最大值 我们不妨设这个数为M_sea 值域比较小所以考虑分块维护. 我们观察到对于给定的一个 \(p\) ,函数 \(y = x \% ...

  4. L3-2 森森快递 (30 分)(贪心+线段树/分块)

    题目链接:https://pintia.cn/problem-sets/1108203702759940096/problems/1108204121661857798 题目大意: 森森开了一家快递公 ...

  5. 2018.09.17 atcoder Tak and Hotels(贪心+分块)

    传送门 一道有意思的题. 一开始想错了,以为一直lowerlowerlower_boundboundbound就可以解决询问,结果交上去TLE了之后才发现时间复杂度是错的. 但是贪心思想一定是对的,每 ...

  6. CF573E Bear and Bowling 贪心、分块、凸包

    传送门 题解搬运工++ 先证明一个贪心做法的正确性:做以下操作若干次,每一次考虑选择没有被选到答案序列中的数加入到答案序列中对答案的贡献,设第\(i\)个位置的贡献为\(V_i\),如果最大的贡献小于 ...

  7. 【贪心】【二维偏序】【权值分块】bzoj1691 [Usaco2007 Dec]挑剔的美食家

    既然题目中的要求满足二维偏序,那么我们很自然地想到将所有东西(草和牛)都读进来之后,对一维(美味度)排序,然后在另一维(价值)中取当前最小的. 于是,Splay.mutiset.权值分块什么的都支持查 ...

  8. bzoj 4464: [Jsoi2013]旅行时的困惑【贪心】

    据说正解是有上下界最小流,但是这种1e5的玩意问什么要跑网络流啊-- 贪心即可,注意一点是可以有多条路径经过一条边-- 以1为根,设d[u][0/1]为u到父亲的边是向下/向上,g记录这个点儿子中不能 ...

  9. BZOJ1086: [SCOI2005]王室联邦(贪心,分块?)

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 2610  Solved: 1584[Submit][Status] ...

随机推荐

  1. sersync+rsync原理及部署

    标签:sersync+rsync部署文档 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://liubao0312.blog.51ct ...

  2. JS实现关闭当前子窗口,刷新父窗口及调用父窗口的方法

    一.js实现关闭当前子窗口,刷新父窗口 JS代码如下: <script> function refreshParent() {  window.opener.location.href = ...

  3. mysql数据类型字段插入空字符串自动填充为0报错

    有一条这样的sql语句, insert into a(id,user_name) values('','abc'); 表示插入字段的时候ID插入是空字符串.这样的情况在mysql5.6版本上执行报错. ...

  4. ora-04021 无法锁表的解决办法

    案例场景: 备库上有一张分区表,在做数据导入出了点问题,需要truncate掉重新导入,在执行truncate table时发生了04021错误. 错误分析: ora-04021的解释是等待锁定对象时 ...

  5. 2018 又一个假期 over 了

    五一假期三天  在家窝三天  早上起床仍感觉没休息好  其实确实没休息好  假期的时间总不愿意拿来补觉用.周末准备去体检,真心恐惧医院的味道,硬着头皮还得上啊.

  6. pycharm自定义代码片段

    pycharm自定义代码片段 目录 (一)通用阶段 0 .新建.py文件模板:2 0 .pycharm中添加自定义代码片段:一图全知道:3 1 .定义类:classin              描述 ...

  7. VS中的配置管理器

    一.    活动解决方案配置   有Debug和Release两个基本选项. Debug:称为 调试版本,它包含调试信息,且不做任何优化,便于程序员调试: Release:称为 发布版本,它往往是进行 ...

  8. nodejs 异步编程 教程(推荐)

    有异步I/O就需要异步编程.本课程将着重讲解在学习node.js中关于异步编程的一些问题,以及如何应对这些问题,帮助node.js初学者快速入门. 地址 http://www.hubwiz.com/c ...

  9. 关于理财和买房 http://shouce.jb51.net/phpcms/ https://www.bj.cmbchina.com/bjtransweb/wsgzd_employ/login.jsp

    对于绝大多数家境普通的年轻人来说,青年阶段无疑是一生中手头最紧的时候.原因很简单,这个阶段花钱最多,挣钱却最少.年轻人收入往往是硬性的低,开支却往往是硬性   的高.已经加班到晕头转向的小职员,很难再 ...

  10. Curl https 访问

    如果访问https的网页,出现: curl: (60) SSL certificate problem: unable to get local issuer certificate 将 将 CURL ...