由题意可知 F(n,x)=((x%A1)%A2)⋯%AnF(n,x) = ((x \% A_1) \% A_2) \cdots \%A_nF(n,x)=((x%A1)%A2)⋯%An
现给出Q个询问,求F(n,x)=yF(n,x) = yF(n,x)=y的解的个数,x<=mx <= mx<=m
对于一个区间[0,x)[0, x)[0,x), 和数m, 若x<m,  [0,x)%m∈[0,x)x < m, \; [0, x) \% m \in [0, x)x<m,[0,x)%m∈[0,x)
若x>m,  [0,x)%mx > m, \; [0, x) \% mx>m,[0,x)%m将得到[x/m][x / m][x/m]个[0,m)[0, m)[0,m)区间和1个[0,x%m)[0, x \% m)[0,x%m)区间
对于每一个mmm, 就把所有>m>m>m的区间都做处理
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
map <int, int> mp;
vector < pair<int, int> > pr;
int main()
{
int T, n, m;
cin >> T;
while (T--) {
mp.clear();
pr.clear();
scanf("%d %d", &n, &m);
mp[m+1] = 1;
int x, q, cnt = 0;
for (int i = 0; i < n; ++i) {
scanf("%d", &x);
//cout << "test: " << x << " " <<mp.rbegin() -> first << '\n';
while (mp.rbegin() -> first > x) {
auto v = *mp.rbegin();
mp.erase(v.first);
mp[x] += v.second * (v.first / x);
if (v.first % x) mp[v.first % x] += v.second;
}
}
auto v = mp.begin();
ll ans = 0;
scanf("%d", &q);
for (int i = 1; i <= q; ++i) {
scanf("%d", &x);
pr.push_back(make_pair(x, i));
}
sort(pr.rbegin(), pr.rend());
auto its = mp.rbegin();
for (auto it = pr.begin(); it != pr.end(); ++it) {
while (its != mp.rend() && its -> first > it -> first) {
cnt += its -> second;
its++;
//cout << "tes: " << its -> first << '\n';
}
(ans += (ll) it -> second * cnt) %= mod;
}
cout << ans << '\n';
}
return 0;
}