A number thesis in a dp coat hhhhh.
It is not difficult to infer the following properties:
1. The number that the i-th item can represent -> a multiple of gcd(V[i] , P).
2. Querying W[i] is actually equivalent to querying gcd(W[i] , P).
3. Under the %P congruence system, the numbers that can be represented by ax + by are the same set as the multiples of gcd(a,b).
It seems a bit awkward, but it is actually very good to prove that the first item is actually an application of a congruence equation; and the second item is because all numbers that can be represented are definitely divisors of P, so W[i] has only The common divisor with P will contribute to the answer; the third is also the fundamental theorem of congruence qwq
Then I found that the divisor of P is at most 10^3 below 10^9, so the actual number of items and queries is only 10^3 level hhhh (when many items are the same as the gcd of P, just take a non-empty subset. Equivalent to selecting this gcd item)
We can first happily dp out f[i][j], which means that the first i items are considered, and the current gcd is the number of solutions for j. Finally, for each divisor k of P, it can be represented by processing (that is, Σf[last][j] * [j|k]).
The above two parts are O(P subnumber ^2), and this problem is easily passed (due to being lazy, I used the hashmap of STL, and I almost got stuck hhhh)
#include<bits/stdc++.h> #define ll long long using namespace std; const int ha = 1000000007; int gcd(int x,int y){ return y?gcd(y,x%y):x;} inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;} inline void ADD(int &x,int y){ x+=y; if(x>=ha) x-=ha;} unordered_map<int,int> N,F[2],ANS; unordered_map<int,int> ::iterator it,IT; int n,now,T,Q,P,nxt,to; inline int read(){ int x=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x; } inline void W(int x){ if(x>=10) W(x/10); putchar(x%10+'0');} inline void update(int x){ if(!N.count(x)) N[x]=2; else (N[x]*=2)%=ha;} inline void dp(){ now=0,nxt=F[0][P]=1; int cnt=0; for(it=N.begin();it!=N.end();now=nxt,nxt^=1,++it){ F[nxt].clear(),cnt++; for(IT=F[now].begin();IT!=F[now].end();++IT){ ADD(F[nxt][IT->first],IT->second); ADD(F[nxt][gcd(IT->first,it->first)],add(it->second,ha-1)*(ll)IT->second%ha); } } for(int i=1;i*(ll)i<=P;i++) if(!(P%i)) ANS[i]=ANS[P/i]=0; for(it=ANS.begin();it!=ANS.end();++it) for(IT=F[now].begin();IT!=F[now].end();++IT) if(!(it->first%IT->first)) ADD(it->second,IT->second); } inline void solve(){ while(Q--) W(ANS[gcd(read(),P)]),puts("");} int main(){ scanf("%d%d%d",&n,&Q,&P); for(int i=1;i<=n;i++) update(gcd(read(),P)); dp(),solve(); return 0; }