整除【NOIP2016提高A组模拟9.21】
来源:互联网 发布:退役特种兵知乎 编辑:程序博客网 时间:2024/06/12 19:07
题目
麦克雷有一个1~n的排列,他想知道对于一些区间,有多少对区间内的数(x,y),满足x能被y整除
样例输入:
第一行包含2个正整数n,m。表示有n个数,m个询问。
接下来一行包含n个正整数,表示麦克雷有的数列。
接下来m行每行包含2个正整数l,r。表示询问区间[l,r]。
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
样例输出:
共 m 行,每行一个整数,表示满足条件的对数。
27
14
8
4
2
1
2
7
9
数据范围:
30%:1<=n,m<=100
100%:1<=n,m<=2*10^5,1<=pi<=n
剖解题目
。。。。。。
思路
区间问题,经过前面的轰炸后一眼就想莫队,然而却不会打。。。
解法
对于一个合法的(x,y),必须要求其两个都在区间[l,r]里才行,只要有一个不在,就是不合法的,我们只要将全部求出来,减去不合法的就行了。
对于y,我们把询问按照第二关键字升序排列,就可以解决。
每次加进一个数,a[i],判断其因数和倍数x是否在区间[1,r]里,在就把c[pos[x]]加一,pos[i]表示i在a数组中的位置,c[i]表示i这个位置可以对答案的贡献。
求和即可。
优化
一:很明显,c这个数组可以用数据结构优化,推荐BIT,segemen tree也行。
二:求n数的因数的时间复杂度是
优化一必须加。优化二看时间,2s内不加也行。
代码
#include<cstdio>#include<algorithm>#include<cstdlib>#include<cmath>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;const int maxn=2*1e5+2;int a[maxn],tree[maxn],pos[maxn];int n,m;bool bz[maxn];struct cy{ int l,r,id,ans;}qs[maxn];bool cmp1(cy a,cy b){ return a.r<b.r;}bool cmp2(cy a,cy b){ return a.id<b.id;}int lowbit(int x){ return x&-x;}void add(int k,int x){ while (k<=n){ tree[k]+=x; k+=lowbit(k); }}int get(int k){ int sum=0; while (k>0){ sum+=tree[k]; k-=lowbit(k); } return sum;}int main(){// freopen("T.in","r",stdin); scanf("%d%d",&n,&m); fo(i,1,n) { scanf("%d",&a[i]); pos[a[i]]=i; } fo(i,1,m){ scanf("%d%d",&qs[i].l,&qs[i].r); qs[i].id=i; } sort(qs+1,qs+m+1,cmp1); fo(i,1,m){ fo(j,qs[i-1].r+1,qs[i].r){ bz[a[j]]=true; fo(k,1,sqrt(a[j])) if (a[j]%k==0) { if (bz[k]) add(pos[k],1); if (bz[a[j]/k]&&a[j]/k!=k) add(pos[a[j]/k],1); } add(pos[a[j]],-1); fo(k,1,n/a[j]) if (bz[k*a[j]]) add(pos[a[j]*k],1); } int x=get(qs[i].r),y=get(qs[i].l-1); qs[i].ans=x-y; } sort(qs+1,qs+m+1,cmp2); fo(i,1,m) printf("%d\n",qs[i].ans);}
0 0
- 【NOIP2016提高A组模拟9.21】整除
- 整除【NOIP2016提高A组模拟9.21】
- 【JZOJ4792】【NOIP2016提高A组模拟9.21】整除
- 【NOIP2016提高A组模拟9.21】矩阵
- 矩阵【NOIP2016提高A组模拟9.21】
- 【JZOJ4790】【NOIP2016提高A组模拟9.21】选数问题
- 【JZOJ4791】【NOIP2016提高A组模拟9.21】矩阵
- 【NOIP2016提高A组模拟9.21】选数问题
- 选数问题【NOIP2016提高A组模拟9.21】
- 【NOIP2016提高A组模拟7.15】立方体
- 计数【NOIP2016提高A组模拟7.15】
- 【NOIP2016提高A组模拟7.17】寻找
- 【NOIP2016提高A组模拟7.17】寻找
- 【NOIP2016提高A组模拟7.17】锦标赛
- 【NOIP2016提高A组模拟7.17】锦标赛
- 【NOIP2016提高A组模拟7.17】锦标赛
- 【NOIP2016提高A组模拟7.15】修路
- 【NOIP2016提高A组模拟7.15】计数
- 认识OpenMP优点
- 头一次进来
- 表单form action的url写法
- ARM嵌入式系统移植环境搭建
- 隐马尔科夫模型(HMM)及其实现
- 整除【NOIP2016提高A组模拟9.21】
- 【SDCC 2016·杭州站】9月22日大数据实战专场精彩呈现
- 手把手教你开发chrome
- 腾讯2016秋招笔试编程题
- 229. Majority Element II
- 通过GRUB命令行来启动Linux操作系统
- 全栈Redux实战
- 文件操作:一次性产生多个文件
- 微信小程序(应用号)开发