【题目链接】
【思路要点】
- 异或FWT模板题。
- 时间复杂度\(O(TM(LogN+LogM))\)。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 70005; const int P = 1e9 + 7; const long long inv = (P + 1) / 2; template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int n, m, res[MAXN], now[MAXN]; int tot, prime[MAXN], f[MAXN]; void FWT(int *a, int N) { for (int len = 2; len <= N; len <<= 1) for (int i = 0; i < N; i += len) for (int j = i, k = i + len / 2; k < i + len; j++, k++) { int tmp = a[j], tnp = a[k]; a[j] = (tmp + tnp) % P; a[k] = (tmp - tnp + P) % P; } } void UFWT(int *a, int N) { for (int len = 2; len <= N; len <<= 1) for (int i = 0; i < N; i += len) for (int j = i, k = i + len / 2; k < i + len; j++, k++) { int tmp = a[j], tnp = a[k]; a[j] = (tmp + tnp) * inv % P; a[k] = (tmp - tnp + P) * inv % P; } } int main() { for (int i = 2; i < MAXN; i++) { if (f[i] == 0) prime[++tot] = f[i] = i; for (int j = 1; j <= tot && prime[j] <= f[i]; j++) { int tmp = prime[j] * i; if (tmp >= MAXN) break; f[tmp] = prime[j]; } } while (scanf("%d%d", &m, &n) != -1) { memset(now, 0, sizeof(now)); int pos = 1, N = 1; while (N <= n) N <<= 1; while (prime[pos] <= n) now[prime[pos++]] = 1; FWT(now, N); m--; memcpy(res, now, sizeof(res)); for (int i = 1; m != 0; i <<= 1) { if (i & m) { m ^= i; for (int j = 0; j < N; j++) res[j] = 1ll * res[j] * now[j] % P; } for (int j = 0; j < N; j++) now[j] = 1ll * now[j] * now[j] % P; } UFWT(res, N); printf("%d\n", res[0]); } return 0; }