【NOIP2016提高A组模拟9.21】整除
来源:互联网 发布:js拆分字符串 编辑:程序博客网 时间:2024/05/21 10:39
题目
- 【NOIP2016提高A组模拟9.21】整除 (Standard IO)
Time Limits: 2000 ms Memory Limits: 262144 KB Detailed Limits
Description
麦克雷有一个1~n的排列,他想知道对于一些区间,有多少对区间内的数(x,y),满足x能被y整除。
Input
第一行包含2个正整数n,m。表示有n个数,m个询问。
接下来一行包含n个正整数,表示麦克雷有的数列。
接下来m行每行包含2个正整数l,r。表示询问区间[l,r]。
Output
共 m 行,每行一个整数,表示满足条件的对数。
Sample Input
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
Sample Output
27
14
8
4
2
1
2
7
9
Data Constraint
30%:1<=n,m<=100
100%:1<=n,m<=2*10^5,1<=pi<=n
正解
我不会告诉你我懒得打tj的
令 X = [1, R] 的合法对数减去 [1, L - 1] 的合法对数,
Y = 一个数属于 [1, L - 1] 另一个数属于 [L, R] 的合法对数,
那么答案就是 X - Y。
我们先将询问按右端点升序排序。
并按原序列顺序从 1 往 n 做,每做到一个位置,便在它左边的数中与它有倍数关
系的数的位置加一。
并统计已经加的次数。
那么每当我们遇到一个右端点与当前做的位置相同时,就可以直接将当前总共加
的次数减去起点到左端点的区间的和就行了。
单点修改和区间求和可以用树状数组。
贴代码
var tree:array[0..700005]of longint; a,b:array[0..200005]of longint; q:array[0..200005,1..3]of longint; ans:array[0..200005]of longint; i,j,k,l,m,n,x,tot,cc:longint;procedure qsort(l,r:longint);var i,j,mid:longint;begin i:=l; j:=r; mid:=q[(i+j) div 2,2]; repeat while q[i,2]<mid do inc(i); while q[j,2]>mid do dec(j); if i<=j then begin q[0]:=q[i]; q[i]:=q[j]; q[j]:=q[0]; inc(i); dec(j); end; until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j);end;procedure change(x,l,r,v:longint);var mid:longint;begin if l=r then inc(tree[x]) else begin mid:=(l+r) div 2; if v<=mid then change(x*2,l,mid,v) else change(x*2+1,mid+1,r,v); tree[x]:=tree[x]+1; end;end;procedure find(x,l,r,s,t:longint);var mid:longint;begin if t<s then exit; if (l=s) and (r=t) then cc:=cc+tree[x] else begin mid:=(l+r) div 2; if t<=mid then find(x*2,l,mid,s,t) else if s>mid then find(x*2+1,mid+1,r,s,t) else begin find(x*2,l,mid,s,mid); find(x*2+1,mid+1,r,mid+1,t); end; end;end;begin // assign(input,'t3.in'); reset(input); // assign(output,'t3.out'); rewrite(output); readln(n,m); for i:=1 to n do begin read(a[i]); b[a[i]]:=i; end; readln; for i:=1 to m do begin readln(q[i,1],q[i,2]); q[i,3]:=i; end; qsort(1,m); x:=0; q[m+1,2]:=n*2; q[0,2]:=0; for i:=1 to n do begin while q[x,2]<i do inc(x); if x>m then break; for j:=1 to trunc(sqrt(a[i])) do if a[i] mod j=0 then begin if b[j]<i then begin change(1,1,n,b[j]); inc(tot); end; if j*j=a[i] then continue; if b[a[i] div j]<i then begin change(1,1,n,b[a[i] div j]); inc(tot); end; end; j:=a[i]; while j<=n do begin if b[j]<=i then begin inc(tot); change(1,1,n,b[j]); end; j:=j+a[i]; end; while q[x,2]=i do begin cc:=0; find(1,1,n,1,q[x,1]-1); ans[q[x,3]]:=tot-cc; inc(x); end; end; for i:=1 to m do writeln(ans[i]); // close(input); close(output);end.
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】计数
- Balanced Lineup_poj3264_rmq ST
- CodeForces 712D Filya and Homework
- hdu5892 -Resident Evil 二维树状数组 + 状态压缩
- MYSQL LIKE 反向查询
- Style属性笔记
- 【NOIP2016提高A组模拟9.21】整除
- Echarts AJAX后台交互
- ESB和SOA到底是什么?
- JAVA从菜鸟【入门】到新手【实习】——汉化(Eclipse)JAVAIDE和JAVADOC(api提示中文)
- 自动化项目配置或用例文件格式推荐--yaml
- [Elasticsearch] 全文搜索
- 将hive数据库中的TBLS表导出到HDFS之上
- python菜鸟升级路--自动化解析生成xml文件
- iOS:系统宏说明(持续更新)