由题意可知
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 <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;
}