題意
- 有一個奇怪的揹包,揹包的重量是放入其中的物品總體積對取模後的結果。現有種體積不同的物品,第種佔用體積爲,每種物品都有無限個。次詢問,每次詢問給出重量,你需要回答有多少种放入物品的方案,能將一個初始爲空的揹包的重量變爲。注意,兩種方案被認爲是不同的,當且僅當放入物品的種類不同。輸出答案對取模的結果。
首先對於一個體積爲的物品,能取到的方案爲,那麼我們可以把這個物品的體積看作,那麼體積相同的物品是可以合併的,又因爲以內一個數的約數個數是級別的,所以物品數就變成了。
我們可以寫出一個方程,設爲取了前個物品,當前選的物品的最小數是的第個約數的方案數,那麼轉移可以用刷表法,枚舉用哪個取轉移,可以轉移到這個數上,再把之前的方案累加上去就做完了。
但是我們現在查詢的話要枚舉一個數的所有約數,是級別的,對於這個我們枚舉一個數倍數,用的時間處理所有的答案,那麼我們就可以的時間回答詢問了。
#include<bits/stdc++.h>
#include<bits/extc++.h>
#define file(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])
#define For(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)
#define FOR(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)
#define debug(x) cout << #x << " = " << x << endl
#define mem(a, b) memset(a, b, sizeof(a))
#define cpy(a, b) memcpy(a, b, sizeof(a))
#define hsb __gnu_pbds::gp_hash_table
#define min(a, b) (a < b ? a : b)
#define max(a, b) (b < a ? a : b)
#define getc getchar_unlocked
#define inf (0x3f3f3f3f)
#define INF (1e18)
#define pb push_back
#define mp make_pair
#define x first
#define y second
#define y1 orzorz
#define div ylsakaaa
typedef unsigned long long ull;
typedef unsigned int uint;
typedef long long ll;
typedef std::pair<ll, int> PLI;
typedef std::pair<int, int> PII;
typedef long double ldb;
typedef double db;
inline int read() {
int _ = 0; static char __; int ___ = 1;
for(__ = getc(); !isdigit(__); __ = getc()) if(__ == '-') ___ = -1;
for(; isdigit(__); __ = getc()) _ = (_ << 3) + (_ << 1) + (__ ^ 48);
return _ * ___;
}
using namespace std;
const int N = 1e6 + 10;
const int M = 4e3 + 10;
const int mod = 1e9 + 7;
int f[M][M], a[N], div[N], pow2[N], s[M], g[M];
int n, q, P, cnt;
void get_div(int mx) {
For(i, 1, mx) if(P % i == 0)
div[++ cnt] = i, div[++ cnt] = P / i;
sort(div + 1, div + cnt + 1);
cnt = unique(div + 1, div + cnt + 1) - div - 1;
}
int main() {
#ifdef ylsakioi
file("4495");
#endif
n = read(), q = read(), P = read();
pow2[0] = 1; get_div(sqrt(P));
For(i, 1, n) {
++ s[lower_bound(div + 1, div + cnt + 1, a[i] = __gcd(P, read())) - div];
pow2[i] = pow2[i - 1] * 2 % mod;
}
sort(a + 1, a + n + 1); n = unique(a + 1, a + n + 1) - a - 1;
For(i, 1, n) {
int tmp = lower_bound(div + 1, div + cnt + 1, a[i]) - div;
f[i][tmp] = pow2[s[tmp]] - 1;
For(j, 1, cnt) {
int to = lower_bound(div + 1, div + cnt + 1, __gcd(a[i], div[j])) - div;
(f[i][to] += (ll)f[i - 1][j] * (pow2[s[tmp]] - 1) % mod) %= mod;
}
For(j, 1, cnt) (f[i][j] += f[i - 1][j]) %= mod;
}
For(j, 1, cnt) For(k, j, cnt)
if(div[k] % div[j] == 0)
(g[k] += f[n][j]) %= mod;
while(q --) printf("%d\n", g[lower_bound(div + 1, div + cnt + 1, __gcd(P, read())) - div]);
return 0;
}