17997 Simple Counting
时间限制:2000MS 内存限制:65535K
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定
Description
Ly is crazy about counting . Recently , he got a simple problem , but he had to learn Gaoshu these days .So , he turns to you for help .
You are given a sequence A with n positive integers numbered from 1 to n , and then expected to answer Q queries .
Each queries contains an interval [L,R] , you should find the number of index i which satisfies :
{i | Ai mod (i-L+1) = 0 , L <= i <= R }
where Ai mod (i-L+1) = 0 means that Ai can be divided by (i-L+1) .
输入格式
The first line of the input is an integer T , indicates the number of test cases . Then T cases followed. For each test case : The first line contains two integers n, Q . The second line contains n positive integers A1, A2, …. An . The next Q line , each line contains two integers L, R. Data range : 1<= T <= 20 1 <= n, Q <= 20000 1<= Ai <= 50000 1<= L <= R <= n
输出格式
For each query, output a single line with an integer indicates the answer expected .
输入样例
2 5 2 1 2 3 4 5 1 5 3 5 6 3 10 7 3 6 24 11 1 3 2 5 5 6
输出样例
5 2 2 3 1
提示
Huge input, scanf is preferred for C/C++. During first sample , for the first query ,A1 mod 1 = 0 , A2 mod 2 = 0 , A3 mod 3 = 0 , A4 mod 4 = 0 ,A5 mod 5 = 0 , so the answer is 5 ; for the second query , A3 mod 1 = 0 , A4 mod 2 = 0 , A5 mod 3 != 0 , so the answer is 2 .
给定n个数字和m次询问,每次给定区间[L, R],然后问a[L] % 1 == 0? a[L + 1] % 2 == 0?,统计答案。
思路:考虑固定左端点L, 就是,对于每一个数字a[i],首先我们已经知道他在数组里的位置是i。
那么如果k是他的约数的话。如果真有询问问到它是否%k==0?,那么这个时候它应该从哪里开始这段区间的询问呢?
应该要在[i - k + 1, ]处吧,因为i - L + 1 = k。得到L等于这个。
然后就可以用一个vector[L]来保存,以L为开始的区间询问,那些位置会是得到ans的。然后二分小于等于R的个数就可以了。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 20000 + 20; vector<int>pos[maxn]; void work() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { pos[i].clear(); } for (int i = 1; i <= n; ++i) { int x; scanf("%d", &x); int end = (int)sqrt(x * 1.0); for (int j = 1; j <= end; ++j) { if (x % j == 0) { int L = i - j + 1; if (L >= 1) { pos[L].push_back(i); } else break; if (x / j == j) continue; L = i - (x / j) + 1; if (L >= 1) { pos[L].push_back(i); } } } } for (int i = 1; i <= n; ++i) { sort(pos[i].begin(), pos[i].end()); } for (int i = 1; i <= m; ++i) { int L, R; scanf("%d%d", &L, &R); int ans = upper_bound(pos[L].begin(), pos[L].end(), R) - pos[L].begin(); printf("%d ", ans); } } int main() { #ifdef local freopen("data.txt","r",stdin); #endif int t; scanf("%d", &t); while (t--) work(); return 0; }