One day, Peter came across a function which looks like:
- F(1, X) = X mod A1.
- F(i, X) = F(i - 1, X) mod Ai, 2 ≤ i ≤ N.
Peter wants to know the number of solutions for equation F(N, X) = Y, where Y is a given number.
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains two integers N and M (2 ≤ N ≤ 105, 0 ≤ M ≤ 109).
The second line contains N integers: A1, A2, ..., AN (1 ≤ Ai ≤ 109).
The third line contains an integer Q (1 ≤ Q ≤ 105) - the number of queries. Each of the following Q lines contains an integer Yi (0 ≤ Yi ≤ 109), which means Peter wants to know the number of solutions for equation F(N, X) = Yi.
Output
For each test cases, output an integer S = (1 ⋅ Z1 + 2 ⋅ Z2 + ... + Q ⋅ ZQ) mod (109 + 7), where Zi is the answer for the i-th query.
Sample Input
1 3 5 3 2 4 5 0 1 2 3 4
Sample Output
8
Hint
The answer for each query is: 4, 2, 0, 0, 0.
题解:
整个区间n个数取模,因为每个数取模后至少变为原来的二分之一,因此复杂度n*logn
node right表示区间的最右端点,cnt表示此区间的个数
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+7;
const int mod=1e9+7;
int n,m,t[maxn],rr[maxn];
struct node
{
int right,cnt;
}c[maxn];
bool operator<(const node &a,const node &b)
{
return a.right<b.right;
}
bool cmp(const node &a,const node &b)
{
return a.right<b.right;
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
priority_queue<node>P;
node r;r.right=m,r.cnt=1;
P.push(r);
for(int i=0;i<n;i++)
{
int x;scanf("%d",&x);
while(P.top().right>=x)
{
node e=P.top();P.pop();
int cnt=e.cnt;
while(!P.empty()&&P.top().right==e.right)
cnt+=P.top().cnt,P.pop();
r.right=x-1,r.cnt=(e.right+1)/x*cnt;
P.push(r);
if((e.right+1)%x)
{
r.right=e.right%x;r.cnt=cnt;
P.push(r);
}
}
}
int tol=0;
while(!P.empty())
{
c[tol].cnt=P.top().cnt;
c[tol++].right=P.top().right;
P.pop();
}
ll ans=0,Q;scanf("%lld",&Q);
sort(c,c+tol,cmp);
memset(t,0,sizeof(t));
t[tol-1]=c[tol-1].cnt;rr[tol-1]=c[tol-1].right;
for(int i=tol-2;i>=0;i--)t[i]=t[i+1]+c[i].cnt,rr[i]=c[i].right;
for(ll i=1;i<=Q;i++)
{
int x;scanf("%d",&x);
int id=lower_bound(rr,rr+tol,x)-rr;
ans=(ans+1LL*t[id]*i)%mod;
}
printf("%lld\n",ans);
}
return 0;
}