由题意可知 F ( n , x ) = ( ( x % A 1 ) % A 2 ) ⋯ % A n F(n,x) = ((x \% A_1) \% A_2) \cdots \%A_n F(n,x)=((x%A1)%A2)⋯%An
现给出Q个询问,求 F ( n , x ) = y F(n,x) = y F(n,x)=y的解的个数, x < = m x <= m x<=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 ) % m x > m, \; [0, x) \% m x>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)区间
对于每一个 m m m, 就把所有 > m >m >m的区间都做处理
AC代码:
#include
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 << " " < 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;
}