题目链接:http://codeforces.com/gym/101102/problem/J
题目大意可以看这个人的:http://www.cnblogs.com/chen9510/p/5933624.html
思路:因为第一位是没有什么用的,因为任意的数都能被1整除,所以我们的范围就变到了0~512。
所以我们预处理处sum(i,j)。其中sum(i,j)表示目前是第i个a[i],能被j整除的个数。

//看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #define mk make_pair #define fi first #define se second #define haha printf("haha ") const int maxn = 1e5 + 5; int sum[maxn][550]; int n, q; int a[maxn]; int main(){ int t; cin >> t; while (t--){ scanf("%d%d", &n, &q); for (int i = 1; i <= n; i++) for (int j = 0; j <= 512; j++) sum[i][j] = 0; for (int i = 1; i <= n; i++){ scanf("%d", a + i); int bit = 0; for (int j = 2; j <= 10; j++){///不要第一位了 if (a[i] % j == 0) bit += (1 << (j - 2)); } for (int j = 0; j <= 512; j++){///因为不要第一位了,所以是512 sum[i][j] = sum[i - 1][j] + ((j & bit) ? 1 : 0); } } while (q--){ int l, r, val; scanf("%d%d%d", &l, &r, &val); if (val % 2) { printf("%d ", r - l + 1); continue; } printf("%d ", sum[r][val >> 1] - sum[l - 1][val >> 1]); } } return 0; }