codeforces 301D Yaroslav and Divisors(树状数组)
Yaroslav has an array p = p1, p2, ..., pn (1 ≤ pi ≤ n), consisting of n distinct integers. Also, he has m queries:
- Query number i is represented as a pair of integers li, ri (1 ≤ li ≤ ri ≤ n).
- The answer to the query li, ri is the number of pairs of integers q, w (li ≤ q, w ≤ ri) such that pq is the divisor of pw.
Help Yaroslav, answer all his queries.
The first line contains the integers n and m (1 ≤ n, m ≤ 2·105). The second line contains n distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n). The following m lines contain Yaroslav's queries. The i-th line contains integers li, ri (1 ≤ li ≤ ri ≤ n).
Print m integers — the answers to Yaroslav's queries in the order they appear in the input.
题目大意:给一个1~n的排列,有m个询问,问L到R之间有多少对数满足一个数是另一个数的约数。
思路:果然数学才是王道……
1~n个数,满足一个数是另一个数的约数的数对,一共有n/1 + n/2 + …… + n/n ≈ nlogn个(大概吧其实我也不会算),也就是32位够了
然后怎么计算L到R有多少对呢?本来想的是用1~R的对数减去1~L-1的对数,结果发现这样算的结果包含了一个属于1~L-1另一个属于L~R的合法对。
于是进一步思考,令x = 1~R的对数减去1~L-1的对数,y = 一个属于1~L-1另一个属于L~R的合法对数,答案ans = x - y。
这个好像没有办法在短时间内在线处理出来,于是采用离线处理。
i从1到n循环,对所有的query.L=i,减去sum[R] - sum[L-1],即上面所说的y(此时L~R的合法对还没被计算出来)。然后找出所有i的倍数,加到sum里面。再对所有的query.R=i,加上sum[R] - sum[L-1],即上面所说的x(此时L~R的合法对已经计算出来了)。
对于这种需要单点更新,区间求值的操作,树状数组可以满足你。
代码(498MS):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int MAXN = ; int a[MAXN], pos[MAXN], tree[MAXN];
int n, m; int lowbit(int x) {
return x & (-x);
} int get_sum(int k) {
int ans = ;
while(k > ) {
ans += tree[k];
k -= lowbit(k);
}
return ans;
} void modify(int k, int val) {
while(k <= n) {
tree[k] += val;
k += lowbit(k);
}
} struct QUERY {
int id, L, R;
bool operator < (const QUERY &rhs) const {
return L < rhs.L;
}
} query[MAXN], query_t[MAXN]; int ans[MAXN]; int main() {
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
pos[a[i]] = i;
}
for(int i = ; i <= m; ++i) {
scanf("%d%d", &query[i].L, &query[i].R);
query_t[i].L = query[i].R;
query_t[i].R = query[i].L;
query[i].id = query_t[i].id = i;
}
sort(query + , query + m + );
sort(query_t + , query_t + m + );
for(int i = , j = , k = ; i <= n; ++i) {
while(j <= m && query[j].L == i) {
ans[query[j].id] -= get_sum(query[j].R) - get_sum(query[j].L - );
++j;
}
for(int p = a[i]; p <= n; p += a[i]) modify(pos[p], );
while(k <= m && query_t[k].L == i) {
ans[query_t[k].id] += get_sum(query_t[k].L) - get_sum(query_t[k].R - );
++k;
}
}
for(int i = ; i <= m; ++i) printf("%d\n", ans[i]);
}
codeforces 301D Yaroslav and Divisors(树状数组)的更多相关文章
- CodeForces 828E DNA Evolution(树状数组)题解
题意:给你一个串k,进行两个操作: “1 a b”:把a位置的字母换成b “2 l r s”:求l到r有多少个字母和s匹配,匹配的条件是这样:从l开始无限循环s形成一个串ss,然后匹配ss和指定区间的 ...
- Codeforces 909C Python Indentation:树状数组优化dp
题目链接:http://codeforces.com/contest/909/problem/C 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现. 现在有一种简化版的Pytho ...
- CodeForces - 597C Subsequences 【DP + 树状数组】
题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...
- Codeforces 635D Factory Repairs【树状数组】
又是看了很久的题目... 题目链接: http://codeforces.com/contest/635/problem/D 题意: 一家工厂生产维修之前每天生产b个,维修了k天之后每天生产a个,维修 ...
- codeforces 570 D. Tree Requests 树状数组+dfs搜索序
链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...
- codeforces E. DNA Evolution(树状数组)
题目链接:http://codeforces.com/contest/828/problem/E 题解:就是开4个数组举一个例子. A[mod][res][i]表示到i位置膜mod余数是res的‘A’ ...
- Codeforces 567D - One-Dimensional Battle Ships - [树状数组+二分]
题目链接:https://codeforces.com/problemset/problem/567/D 题意: 在一个 $1 \times n$ 的网格上,初始摆放着 $k$ 只船,每只船的长度均为 ...
- codeforces#1167F. Scalar Queries(树状数组+求贡献)
题目链接: https://codeforces.com/contest/1167/problem/F 题意: 给出长度为$n$的数组,初始每个元素为$a_i$ 定义:$f(l, r)$为,重排$l$ ...
- codeforces 1288E. Messenger Simulator(树状数组)
链接:https://codeforces.com/contest/1288/problem/E 题意:序列p的长度为n,初始序列为1 2 3 4 ...n,然后有m次操作,每次指定序列中一个数移动到 ...
随机推荐
- c#随便聊聊数据库操作
最近在学习web后台以及Python,到了程序员的转折年纪了,哎.估计很久不会写博文了.言归正传. 在原理的数据库连接池HiKari项目上.我扩展了独立的3个库,说是3个库,其实原本该是一个库.先聊聊 ...
- GIT更新一其中一个提交版本
有一小朋友刚才SVN转到GIT,最近老是咨询怎么才svn update -rXXXXX 在git其实也不麻烦,就是git checkout的事情,不管是分支还是TAG,都会有一个HASH版本号 1. ...
- idea 引入多项目
1.先导入总包 2.右侧mavenmaven,选择parent的pom.xml 3.右上角“Project Structure”检查SDK
- 使用Screen管理远程会话
在本地开发时,经常需要使用远程连接到Linux服务器,一开始我自己都是有几个远程就开几个SSH窗口,这种方法很原始很直接,但每次都受够了密码输入,即使用了SSH免密码登录,也会觉得每次输入SSH的 ...
- Set的源码分析
Set的内部实现其实是一个Map.即HashSet的内部实现是一个HashMap,TreeSet的内部实现是一个TreeMap,LinkedHashSet的内部实现是一个LinkedHashMap. ...
- hive 学习系列六 hive 去重办法的思考
方法1,建立临时表,利用hive的collect_set 进行去重. create table if not exists tubutest ( name1 string, name2 string ...
- 第九篇:S3C2400时钟体系
S3C2400时钟体系 S3C2400时钟配置流程 该学习板使用了外部晶振12Mhz 晶振--->经过MPLL(锁相环) --->(倍频得到)FCLK--->(对FCLK分频得到)H ...
- Leecode刷题之旅-C语言/python-349两个数组的交集
/* * @lc app=leetcode.cn id=349 lang=c * * [349] 两个数组的交集 * * https://leetcode-cn.com/problems/inters ...
- 树莓派编译程序时报错:virtual memory exhausted: Cannot allocate memory
一.原因分析: 树莓派内存太小,编译程序会出现virtual memory exhausted: Cannot allocate memory的问题,可以用swap扩展内存的方法. 二.解决方法: 安 ...
- c语言杨氏矩阵算法
杨氏矩阵 有一个二维数组.数组的每行从左到右是递增的,每列从上到下是递增的.在这样的数组中查找一个数字是否存在.时间复杂度小于O(N);数组:1 2 32 3 43 4 5 1 3 42 4 54 5 ...