【JZOJ4792】【NOIP2016提高A组模拟9.21】整除
题目描述
麦克雷有一个1~n的排列,他想知道对于一些区间,有多少对区间内的数(x,y),满足x能被y整除。
输入
第一行包含2个正整数n,m。表示有n个数,m个询问。
接下来一行包含n个正整数,表示麦克雷有的数列。
接下来m行每行包含2个正整数l,r。表示询问区间[l,r]。
输出
共 m 行,每行一个整数,表示满足条件的对数。
样例输入
10 9
1 2 3 4 5 6 7 8 9 10
1 10
2 9
3 8
4 7
5 6
2 2
9 10
5 10
4 10
样例输出
27
14
8
4
2
1
2
7
9
数据范围
30%:1<=n,m<=100
100%:1<=n,m<=2*10^5,1<=pi<=n
解法
对于一个区间[l,r],它的答案=区间[1,r]中的总贡献-区间[1,r]中[1,l-1]的贡献。
证明:
显然,区间[l,r]的答案=区间[1,r]的答案-区间[1,l]的答案-所有(a[i],a[j])的贡献。(其中i∈[1,l],j∈[1,r])
而又,区间[1,l]的答案+所有(a[i],a[j])的贡献=区间[1,r]中[1,l-1]的贡献;
所以区间[l,r]的答案=区间[1,r]中的总贡献-区间[1,r]中[1,l-1]的贡献。
如果把区间按右端点升序排序,那么使用扫描线即可将问题转化为:
区间[1,r]中,任意区间贡献和。
用树状数组维护即可。
代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define ll long long
#define ln(x,y) ll(log(x)/log(y))
#define sqr(x) ((x)*(x))
using namespace std;
const char* fin="aP3.in";
const char* fout="aP3.out";
const ll inf=0x7fffffff;
const ll maxn=200007,maxt=maxn*5;
ll n,m,i,j,k,l,r,ks,cnt;
ll tmp=0;
ll a[maxn],b[maxn],c[maxn];
ll ans[maxn];
ll hh[maxn];
bool bz[maxn];
struct q{
ll l,r,id;
}qu[maxn];
bool cmp(q a,q b){
return a.r<b.r;
}
void change(ll v,ll v1){
if (!bz[v]) return;
v=b[v];
cnt+=v1;
for (;v<=n;v+=v&-v) c[v]+=v1;
}
ll getsum(ll v){
ll x=0;
for (;v;v-=v&-v) x+=c[v];
return x;
}
ll getsum(ll l,ll r){
return getsum(r)-getsum(l-1);
}
void join(ll v){
ll i,j,k;
bz[a[v]]=true;
for (i=1;i<=(ll)(sqrt(a[v]));i++){
if (a[v]%i==0){
change(a[v]/i,1);
if (i*i!=a[v]) change(i,1);
}
}
for (i=a[v]*2;i<=n;i+=a[v]) change(i,1);
}
int main(){
scanf("%d%d",&n,&m);
ks=sqrt(n);
for (i=1;i<=n;i++){
scanf("%d",&a[i]);
b[a[i]]=i;
}
for (i=1;i<=m;i++){
scanf("%d%d",&qu[i].l,&qu[i].r);
qu[i].id=i;
}
sort(qu+1,qu+m+1,cmp);
r=0;
for (i=1;i<=m;i++){
while (r<qu[i].r) {
join(++r);
}
ans[qu[i].id]=cnt-getsum(qu[i].l-1);
}
for (i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}
启发
离线的区间问题归结为:
莫队算法
范围
对于已知区间,给其加入元素或删除元素以较低复杂度完成。
则适用莫队算法。
扩展
如果加入元素简单,删除元素难,那么就可以使用只增莫队算法。
参考这一题。
分块
坑待填
区间拆分扫描线
范围
当[1,i]容易计算时,且区间[l,r]可拆分成[1,r]和[1,l-1];
则适用区间拆分扫描线。
参考这一题。
扩展
如果[l,r]拆分后满足ans([l,r])=ans([1,r])-ans([1,l-1])-ans(分属于[1,l-1],[l,r]);
那么是可以将ans([l,r])=ans([1,r])-[1,r]下[1,l-1]的贡献。
参考本题。
【JZOJ4792】【NOIP2016提高A组模拟9.21】整除的更多相关文章
- [jzoj 4722] [NOIP2016提高A组模拟8.21] 跳楼机 解题报告 (spfa+同余)
题目链接: http://172.16.0.132/senior/#main/show/4722 题目: DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧.Srwudi的家是一幢h层的摩天 ...
- 【JZOJ4791】【NOIP2016提高A组模拟9.21】矩阵
题目描述 在麦克雷的面前出现了一个有n*m个格子的矩阵,每个格子用"."或"#"表示,"."表示这个格子可以放东西,"#" ...
- 【JZOJ4790】【NOIP2016提高A组模拟9.21】选数问题
题目描述 在麦克雷的面前有N个数,以及一个R*C的矩阵.现在他的任务是从N个数中取出R*C个,并填入这个矩阵中.矩阵每一行的法值为本行最大值与最小值的差,而整个矩阵的法值为每一行的法值的最大值.现在, ...
- JZOJ 4732. 【NOIP2016提高A组模拟8.23】函数
4732. [NOIP2016提高A组模拟8.23]函数 (Standard IO) Time Limits: 1500 ms Memory Limits: 262144 KB Detailed ...
- 【NOIP2016提高A组模拟9.14】数列编辑器
题目 分析 比赛上,没有注意到询问只询问光标前面,于是只打了个暴力. 因为询问只询问光标前面,首先,当光标向后每移动到一个位置,顺便将这个位置的前缀和,和最大前缀和求出来. 总之,模拟 #includ ...
- 【NOIP2016提高A组模拟9.24】总结
第一题纯模拟,结果那个出题人脑子似乎进水了,空间限制开了1G!!! 导致我捉摸了半天为什么空间要开那么大,最后只能得出上面的结论. 第二题是个矩阵快速幂,比赛上我没把递推式求出来,但是根据各种乱搞,得 ...
- 【JZOJ4711】【NOIP2016提高A组模拟8.17】Binary
题目描述 输入 输出 样例输入 6 6 8 9 1 13 9 3 1 4 5 2 6 9 1 3 7 2 7 7 1 6 1 2 11 13 样例输出 45 19 21 数据范围 解法 40%暴力即可 ...
- 【JZOJ4747】【NOIP2016提高A组模拟9.3】被粉碎的线段树
题目描述 输入 第一行包括两个正整数,N ,M ,分别表示线段树的宽以及询问次数. 以下N-1 行以先序遍历(dfs深搜顺序)描述一个小R线段树,每行一个正整数表示当前非叶子节点的 mid,保证每个节 ...
- 【JZOJ4746】【NOIP2016提高A组模拟9.3】树塔狂想曲
题目描述 相信大家都在长训班学过树塔问题,题目很简单求最大化一个三角形数塔从上往下走的路径和.走的规则是:(i,j)号点只能走向(i+1,j)或者(i+1,j+1).如下图是一个数塔,映射到该数塔上行 ...
随机推荐
- 错误 2 error C2059: 语法错误:“::”
设置项目属性,在预定义处理器中添加定义NOMINMAX来禁止使用Vsual C++的min/max宏定义. 项目属性 ——> C/C++ ——> 预处理器 ——> 预处理器定义 ...
- BZOJ 1822[JSOI2010]Frozen Nova 冷冻波
网络流+二分. n^3枚举判断每个巫妖可以攻击的精灵,向其连1的边,每个精灵向汇点连1的边. 二分答案,修改源点流向每个巫妖的cap,跑最大流看是否等于精灵数. 恩,看起来没什么毛病. 然后狂WA不止 ...
- 20191004-gugugu公告
作者洗手不干了,所以以后可能会不写考试反思而是要写题解了…… ××这是$Day7$,于是我跪了 (不会,于是准备自己$YY$) 加油啊$LNC$你一定能$AK$的(雾 但是他因为太愧疚而没有打症结而是 ...
- 《机器学习及实践--从零开始通往Kaggle竞赛之路》
<机器学习及实践--从零开始通往Kaggle竞赛之路> 在开始说之前一个很重要的Tip:电脑至少要求是64位的,这是我的痛. 断断续续花了个把月的时间把这本书过了一遍.这是一本非常适合基于 ...
- mysql基础教程(一)-----概述、安装、查询
概述 好处 •实现数据持久化 •使用完整的管理系统统一管理,易于查询 概念 DB 数据库(database):存储数据的“仓库”.它保存了一系列有组织的数据. DBMS 数据库管理系统(Databas ...
- Spring AOP(一)--基本概念
AOP(Aspect Oriented Programing),意为面向切面编程,其实看了很多书本的介绍和说明,我觉得这些解释都太过书面,也可能是翻译的原因,总觉得还是不太懂,也难以理解这种叫法,尤其 ...
- 装配SpringBean(四)--注解装配之组件扫描
前两篇文章我总结了通过XML方式装配bean的实现方式,虽然比较简单,但是需要配置很多,很多时候我们都会使用注解进行装配.使用注解的方式可以减少XML的配置,既能实现XML的功能,还提供了自动装配功能 ...
- MyBatis映射器(一)--多参数传递方式
在mybatis映射器的接口中,一般在查询时需要传递一些参数作为查询条件,有时候是一个,有时候是多个.当只有一个参数时,我们只要在sql中使用接口中的参数名称即可,但是如果是多个呢,就不能直接用参数名 ...
- webService学习五(插入片,---监控方法)
WS Explorer工具的使用: 1- web服务浏览器 2-将对应的路径copy到这里 - 3- 4-- 5-- 6--请求的数据: 7--相应数据 二.使用TCP/IP Monitor-拦截HT ...
- Laravel使用EasyWechat 进行微信支付
微信支付和EasyWeChat这个包都是巨坑, 文档写的稀烂, 记录下防止以后又重复踩坑: 安装教程在这: https://www.jianshu.com/p/82d688e1fd2a