题解、
2026-01-10 17:11:23
发布于:上海
3阅读
0回复
0点赞
#include <bits/stdc++.h>
#define rep(i, j, k) for(int i = j; i <= k; ++i)
#define dep(i, j, k) for(int i = j; i >= k; --i)
#define SIZE(x) ((int)x.size())
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn = 1e5 + 5;
const int P = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int n, G, L, Q, x, pow2[maxn], U, l[maxn], r[maxn], siz[maxn], N, ans[1 << 17];
vector<pair<int, int> > facL, data;
inline int read() {
char ch = getchar(); int u = 0, f = 1;
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); }
while(isdigit(ch)) { u = u * 10 + ch - 48; ch = getchar(); } return u * f;
}
inline int pls(int x, int y) { x += y; return x >= P ? x - P : x; }
inline int dec(int x, int y) { x -= y; return x < 0 ? x + P : x; }
inline void GetFac(int x, vector<pair<int, int> > &fac) {
for(int i = 2; i * i <= x; i++) if(x % i == 0) {
int cnt = 0;
while(x % i == 0) x /= i, cnt++;
fac.pb(mp(i, cnt));
}
if(x != 1) fac.pb(mp(x, 1));
}
inline void Binout(int S) {
stack<int> st;
while(S) st.push(S & 1), S >>= 1;
rep(i, 1, N - st.size()) putchar('0');
while(st.size()) putchar(st.top() + '0'), st.pop();
putchar('\n');
}
inline pair<int, int> GetState(int x) {
int S = 0, y = x;
rep(i, 0, SIZE(facL) - 1) {
int cnt = 0;
while(x % facL[i].first == 0) x /= facL[i].first, cnt++;
S |= (cnt == l[i]) << i;
S |= (cnt == r[i]) << i + SIZE(facL);
}
return mp(y, S);
}
inline void PreSolve() {
GetFac(L, facL);
pow2[0] = 1; N = SIZE(facL) << 1; U = (1 << N) - 1;
rep(i, 1, U) pow2[i] = pls(pow2[i - 1], pow2[i - 1]);
rep(i, 0, SIZE(facL) - 1) {
r[i] = facL[i].second;
int x = G;
while(x % facL[i].first == 0) l[i]++, x /= facL[i].first;
}
for(int i = 1; 1ll * i * i <= L; i++) if(L % i == 0) {
if(i % G == 0 && i <= n) data.pb(GetState(i));
if(i * i != L && (L / i) % G == 0 && (L / i) <= n) data.pb(GetState(L / i));
}
sort(data.begin(), data.end());
for(auto v : data) siz[v.second]++;
rep(i, 0, N - 1) rep(S, 0, U) if(S >> i & 1) siz[S] += siz[S ^ (1 << i)];
}
inline int Solve(int x, int rnt = 0) {
auto it = *lower_bound(data.begin(), data.end(), mp(x, 0));
if(ans[it.second] != -1) return ans[it.second];
int T = it.second, S = U ^ T; rnt = __builtin_popcount(T) & 1 ? dec(rnt, pow2[siz[T] - 1]) : pow2[siz[T] - 1];
for(int S1 = S; S1; S1 = (S1 - 1) & S)
if(__builtin_popcount(S1 | T) & 1) rnt = dec(rnt, pow2[siz[S1 | T] - 1]);
else rnt = pls(rnt, pow2[siz[S1 | T] - 1]);
return ans[it.second] = rnt;
}
int main() {
n = read(); G = read(); L = read(); Q = read();
if(L % G) { rep(i, 1, Q) puts("0"); return 0; }
PreSolve();
memset(ans, -1, sizeof(ans));
rep(i, 1, Q) {
x = read();
if(x % G != 0 || L % x != 0 || x > n) puts("0");
else printf("%d\n", Solve(x));
}
return 0;
}
这里空空如也







有帮助,赞一个