BZOJ5302 [HAOI2018] Strange Backpack [Number Theory + dp]

topic

Little CC is very good at the knapsack problem. He has a strange knapsack. This knapsack has a parameter PP. When he puts several items into the knapsack, the weight of the knapsack is the result of taking the model of the total volume of the items to PP. Now there are nn kinds of objects with different volumes in small CC, the iith occupancy volume is V_iV
i
​ , and each kind of object has an infinite number. He will ask qq times, and each time he asks the weight w_iwi
​ , you need to answer how many ways to put items, which can change the weight of
an initially empty knapsack to w_iwi
​ .
Note that the two schemes are considered to be different if and only if the types of items placed are different, regardless of the number of items placed in each. It is not difficult to find that the total number of solutions is 2^n2
n
. Since the answer may be large, you only need to output the result of the answer modulo 1e9+7.

input format

Read data from the file knapsack.inknapsack.in. The first line contains three integers nn , qq , PP , and the meaning is shown in the description of the problem. The next line of nn integers represents V_iV
i
​ . The next line of qq integers represents w_iw
i
.

output format

Output to the file knapsack.outknapsack.out. Output qq lines, each with an integer representing the answer.

input sample

3 3 6
1 3 4
5 2 3

Sample output

5
6
6

hint

answer

Consider the linear combination form of \(ax + by\) in number theory, which can only represent a multiple of \ (gcd(a,b)\)
\(ax \mod P\) can be written as \(ax - Py\) , which is also a linear combination of \(a\) and \(P\)
, so an item can only represent a multiple of \(gcd(V[i], P)\) We only need to ask for the approximate value
of all \(P\) number of solutions, for query \(W[i]\) , we only need to query the number of solutions of \(gcd(W[i],P)\)

Let \(f[i][j]\) represent the number of solutions where the first \(i\) numbers make up the divisor \(j\) , and the transfer can be done

The divisor within \(10^9\) does not exceed \(10^3\)

It is recommended not to use STL

#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
#define MAP map<int,int>
#define res register 
using namespace std;
const int maxn = 1000005,maxm = 100005,INF = 1000000000,md = 1e9 + 7;
inline int read(){
    res int out = 0,flag = 1; res char c = getchar();
    while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    return out * flag;
}
inline void write(int x){if (x >= 10) write(x / 10); putchar(x % 10 + '0');}
MAP f[2],Ans,A;
MAP::iterator it,IT;
int n,m,P;
inline int add2(int x,int y){x += y; if (x >= md) x -= md; return x;}
inline void add(int& x,int y){x += y; if (x >= md) x -= md;}
inline int gcd(int a,int b){return b ? gcd(b,a % b) : a;}
void init(){
    int tmp,p = 1; f[0][P] = 1;
    for (IT = A.begin(); IT != A.end(); IT++,p ^= 1){
        f[p].clear();
        for (it = f[p ^ 1].begin(); it != f[p ^ 1].end(); it++){
            add(f[p][it->first],it->second);
            tmp = gcd(IT->first,it->first);
            add(f[p][tmp],1ll * add2(IT->second,md - 1) * it->second % md);
        }
    }
    p ^= 1;
    for (res int i = 1; 1ll * i * i <= P; i++) Ans[i] = Ans[P / i] = 0;
    for (it = Ans.begin(); it != Ans.end(); it++)
        for (IT = f[p].begin(); IT != f[p].end(); IT++)
            if (it->first % IT->first == 0)
                add(it->second,IT->second);
}
void solve(){
    while (m--) write(Ans[gcd(read(),P)]),puts("");
}
int main(){
    n = read(); m = read(); P = read();
    int x;
    for (res int i = 1; i <= n; i++){
        x = gcd(read(),P);
        if (!A.count(x)) A[x] = 2;
        else A[x] = A[x] * 2 % md;
    }
    init();
    solve();
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325017965&siteId=291194637