zoj 3940

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.
Where A is an integer array of length N, X is a non-negative integer no greater than M.
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.
题意:给出一组数,现给定一个数x,那么可以得到一个值x%a1%a2,,,%an,先给出q个询问y,问对于每个询问有多少个x(1-m之间)取模后可以到y;
做法:把数进行分段,记录这样的二元组:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+100;
const int mod = 1e9+7;
map<int,int> mp;
int pos[N];
int sum[N];
int n,m;
int main(){
    int T;
    cin >> T;
    while(T--){
        int n,m;
        scanf("%d %d",&n,&m);
        mp.clear();
        mp[m] = 1;
        for(int i = 1;i <= n;i ++){
            int now;
            scanf("%d",&now);
            auto iter = mp.lower_bound(now);
            while(iter != mp.end()){
                mp[now-1] += iter->first/now*iter->second;
                mp[(iter->first)%now] +=iter->second;
                mp.erase(iter ++);
            }
        }
        int sz = mp.size();
        auto iter = mp.begin();
        sum[sz+1] = 0;
        for(int i= 1;i <= sz;i ++){
            pos[i] = iter->first;
            sum[i] = iter->second;
            iter ++;
        }
        for(int i = sz;i >= 1;i --) sum[i] += sum[i+1];
        int ans= 0;
        int qs;
        cin >> qs;
        for(int i= 1;i <= qs;i ++){
            int now;
            scanf("%d",&now);
            int tmp = lower_bound(pos+1,pos+sz+1,now)-pos;
            ans = (ans+1LL*sum[tmp]*i)%mod;
        }
        cout << ans << endl;

    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/zstu_zy/article/details/79682945
ZOJ