#include
#include
#include
using namespace std;
const int maxlcm = 2520;
typedef long long ll;
ll dp[20][50][2530];
int Hash[2530];
ll nums[20];
ll gcd(ll a, ll b) {
if (b == 0) return a;
return gcd(b, a % b);
}
ll dfs(ll pos, ll sum, ll lcm, bool limit) {
if (pos == -1) {
return sum % lcm == 0;
}
if (limit == false && dp[pos][Hash[lcm]][sum] != -1) return dp[pos][Hash[lcm]][sum];
ll ans = 0;
int up = limit ? nums[pos] : 9;
for (int i = 0; i <= up; i++) {
ans += dfs(pos - 1, (sum * 10 + i) % maxlcm, i ? i * lcm / gcd((ll)i, lcm) : lcm, limit && i == up);
}
if (limit == 0) dp[pos][Hash[lcm]][sum] = ans;
return ans;
}
ll solve(ll N) {
int p = 0;
while (N) {
nums[p++] = N % 10;
N /= 10;
}
return dfs(p - 1, 0, 1, true);
}
int main() {
int T;
scanf("%d", &T);
memset(dp, -1, sizeof dp);
int cnt = 0;
for (int i = 1; i <= maxlcm; i++) {
if (maxlcm % i == 0) Hash[i] = cnt++;
}
while (T--) {
ll l, r;
cin >> l >> r;
cout << solve(r) - solve(l - 1) << endl;
}
return 0;
}
#include
#include
#include
#include
using namespace std;
const int maxn = 100010;
int st[maxn], prime[maxn], cnt;
void sieve(int N) {
for (int i = 2; i <= N; i++) {
if (!st[i]) prime[cnt++] = i;
else {
for (int j = 0; prime[j] <= N / i; j++) {
st[prime[j] * i] = true;
if (i % prime[j] == 0) break;
}
}
}
}
int N;
bool vis[maxn];
typedef pair<int, int> P;
vector<P> ans;
int main() {
sieve(maxn - 1);
scanf("%d", &N);
for (int i = 1; i < cnt; i++) {
int p = prime[i];
vector<int> res;
for (int j = p; j <= N; j += p) {
if (!vis[j]) res.push_back(j);
}
int num = res.size();
if (num == 1) continue;
if (num & 1) {
ans.push_back(P(res[0], res[2]));
vis[res[0]] = vis[res[2]] = true;
for (int j = 3; j < num; j += 2) {
ans.push_back(P(res[j], res[j + 1]));
vis[res[j]] = vis[res[j + 1]] = true;
}
}
else {
for (int j = 0; j < num; j += 2) {
ans.push_back(P(res[j], res[j + 1]));
vis[res[j]] = vis[res[j + 1]] = true;
}
}
}
for (int i = 2; i <= N; i += 2) {
if (vis[i]) continue;
int p1 = i;
i += 2;
while (i <= N && vis[i]) i += 2;;
if(i <= N && !vis[i]) ans.push_back(P(p1, i));
}
printf("%d\n", ans.size());
for (auto p : ans) {
printf("%d %d\n", p.first, p.second);
}
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
typedef complex<double> Comp;
const int maxn = 800010;
int n, m, N, M, K, L;
char S[maxn], T[maxn];
Comp A[maxn], B[maxn];
int vis[5][maxn], cnt[5], id[256], ans[maxn], rev[maxn];
const double PI = 2 * asin(1);
void FFT(Comp* a, int f) {
for (int i = 0; i < n; i++) if (rev[i] > i) swap(a[i], a[rev[i]]);
for (int i = 1; i < n; i <<= 1) {
Comp wn(cos(PI / i), sin(PI / i));
for (int p = i << 1, j = 0; j < n; j += p) {
Comp w(1, 0);
for (int k = 0; k < i; k++, w *= wn) {
Comp x = a[k + j], y = w * a[k + j + i];
a[k + j] = x + y; a[k + j + i] = x - y;
}
}
}
if (f == -1) reverse(a + 1, a + n);
}
int main() {
scanf("%d%d%d", &N, &M, &K);
scanf("%s%s", S + 1, T + 1);
//计算数组
id['A'] = 1, id['G'] = 2, id['T'] = 3, id['C'] = 4;
for (int l = 0, r = 0, i = 1; i <= N; i++) {
while (l < N && l < i - K) cnt[id[S[l++]]]--;
while (r < N && r < i + K) cnt[id[S[++r]]]++;
for (int j = 1; j <= 4; j++) if (cnt[j]) vis[j][i] = 1;
}
m = N + M;
for (n = 1; n <= m; n <<= 1) L++;
for (int i = 0; i < n; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (L - 1));
for (int k = 1; k <= 4; k++) {
memset(A, 0, sizeof A);
memset(B, 0, sizeof B);
for (int i = 1; i <= N; i++) {
if (vis[k][i] == 1) A[i - 1] = 1;
}
for (int i = 1; i <= M; i++) {
if (id[T[i]] == k) B[M - i] = 1;
}
FFT(A, 1), FFT(B, 1);
for (int i = 0; i < n; i++) A[i] *= B[i];
FFT(A, -1);
for (int i = 0; i < n; i++) ans[i] += (ll)(A[i].real() + 0.5) / n;
}
int res = 0;
for (int i = 0; i < n; i++) if (ans[i] == M) res++;
printf("%d\n", res);
return 0;
}
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 200010;
ll a[maxn];
int N;
vector<ll> divisor(ll N) {
vector<ll> res;
for (ll i = 2; i <= N / i; i++) {
if (N % i == 0) {
res.push_back(i);
while (N % i == 0) N /= i;
}
}
if (N > 1) res.push_back(N);
return res;
}
unordered_set<ll> tried;
int main() {
scanf("%d", &N);
for (int i = 0; i < N; i++) scanf("%lld", &a[i]);
//srand(NULL);
ll ans = 1e9;
for (int i = 0; i < 50; i++) {
unordered_set<ll> primes;
int id = rand() * rand() % N;
//printf("*** %d\n", id);
for (ll j = -1; j <= 1; j++) {
if (a[id] + j == 0LL) continue;
vector<ll> v = divisor(a[id] + j);
for (auto u : v) primes.insert(u);
}
if(i == 0) primes.insert(2);
for (auto p : primes) {
ll res = 0;
if (tried.count(p)) continue;
tried.insert(p);
for (int j = 0; j < N; j++) {
if (a[j] < p) res += p - a[j];
else {
res += min(a[j] % p, p - (a[j] % p));
}
}
//printf("### %lld %lld\n", p, res);
ans = min(res, ans);
}
}
printf("%lld\n", ans);
return 0;
}
#include
#include
#include
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 300010;
int cnt[maxn], mx, N;
ll dp[10][maxn], fact[maxn], infact[maxn];
ll mod_pow(ll x, ll n) {
ll res = 1;
while (n) {
if (n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
ll C(ll a, ll b) {
if (a < b) return 0;
return fact[a] * infact[b] % mod * infact[a - b] % mod;
}
int main() {
fact[0] = infact[0] = 1;
for (ll i = 1; i <= 300000; i++) {
fact[i] = fact[i - 1] * i % mod;
infact[i] = infact[i - 1] * mod_pow(i, mod - 2) % mod;
}
scanf("%d", &N);
for (int i = 0; i < N; ++i) {
int x;
scanf("%d", &x);
++cnt[x];
mx = max(mx, x);
}
for (int i = 1; i <= mx; ++i) {
for (int j = 2 * i; j <= mx; j += i) {
cnt[i] += cnt[j];
}
}
for (int i = 1; i <= 7; i++) {
for (int j = mx; j >= 1; j--) {
dp[i][j] = C(cnt[j], i);
for (int k = 2; k * j <= mx; k++) {
dp[i][j] = (dp[i][j] - dp[i][k * j] + mod) % mod;
}
}
if (dp[i][1]) {
printf("%d\n", i);
return 0;
}
}
printf("-1\n");
return 0;
}
#include
#include
#include
using namespace std;
const int maxn = 100010;
typedef long long ll;
typedef unordered_map<ll, int> um;
um ma, mb, c1, c2;
int N, M, Y1, Y2;
int main() {
scanf("%d%d", &N, &Y1);
ll x;
int cntmax_a = 0, cntmax_b = 0;
//因为增长步数可以是0,所以底下是特判。
for (int i = 0; i < N; i++) {
scanf("%lld", &x);
++ma[x];
cntmax_a = max(cntmax_a, ma[x]);
}
scanf("%d%d", &M, &Y2);
for (int i = 0; i < M; i++) {
scanf("%lld", &x);
++mb[x];
cntmax_b = max(cntmax_b, mb[x]);
}
int ans = cntmax_a + cntmax_b;
for (ll u = 1; u <= 1000000000; u <<= 1) {
c1.clear(), c2.clear();
for (auto p : ma) {
c1[p.first % (2 * u)] += p.second;
}
for (auto p : mb) {
c2[p.first % (2 * u)] += p.second;
}
for (auto p : c1) {
ans = max(ans, p.second + c2[(p.first + u) % (2 * u)]);
}
for (auto p : c2) {
ans = max(ans, p.second + c1[(p.first + u) % (2 * u)]);
}
}
printf("%d\n", ans);
return 0;
}
#include
#include
#include
using namespace std;
const int maxn = 200010;
typedef long long ll;
ll N, a[maxn], b[maxn], c[maxn], cnt[40];
bool check() {
for (int i = 1; i <= N; i++) {
ll ckb = 0, ckc = 0;
for (int j = 0; j <= 30; j++) {
if ((a[i] >> j) & 1) {
ckb += cnt[j] * (1LL << j);
ckc += (1LL << j) * N;
}
else {
ckc += cnt[j] * (1LL << j);
}
}
if (ckb != b[i] || ckc != c[i]) return false;
}
return true;
}
int main() {
scanf("%lld", &N);
ll sumbc = 0;
for (int i = 1; i <= N; i++) {
scanf("%lld", &b[i]);
sumbc += b[i];
}
for (int i = 1; i <= N; i++) {
scanf("%lld", &c[i]);
sumbc += c[i];
}
ll suma = sumbc / 2 / N;
for (int i = 1; i <= N; i++) {
a[i] = (b[i] + c[i] - suma) / N;
for (int j = 0; j <= 30; j++) {
cnt[j] += ((a[i] >> j) & 1);
}
}
if (check()) {
for (int i = 1; i <= N; i++) printf("%lld%c", a[i], i == N ? '\n' : ' ');
}
else printf("-1\n");
return 0;
}
题解1
题解2
题解3
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 310;
typedef long long ll;
ll dp[maxn][maxn], N, fact[maxn], infact[maxn];
const ll mod = 1e9 + 7;
ll mod_pow(ll x, ll n) {
ll res = 1;
while (n) {
if (n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
unordered_map<ll, ll> tot;
vector<ll> cnt;
ll C(ll m, ll n) {
return fact[m] * infact[n] % mod * infact[m - n] % mod;
}
int main() {
fact[0] = infact[0] = 1;
for (ll i = 1; i < maxn; i++) {
fact[i] = i * fact[i - 1] % mod;
infact[i] = infact[i - 1] * mod_pow(i, mod - 2) % mod;
}
dp[0][0] = 1;
scanf("%lld", &N);
for (int i = 0; i < N; i++) {
ll x;
scanf("%lld", &x);
bool flag = false;
for (auto p : tot) {
ll u = p.first;
ll res = (ll)(sqrt(u * x) + 0.5);
if (u * x == res * res) {
flag = true;
tot[u]++;
break;
}
}
if (!flag) tot[x]++;
}
for (auto p : tot) {
cnt.push_back(p.second);
}
int sz = tot.size();
dp[0][0] = 1;
for (int i = 1; i <= sz; i++) {
for (int k = 1; k <= N; k++) {
for (int j = 1; j <= min((int)cnt[i - 1], k); j++) {
dp[i][k] = (dp[i][k] + dp[i - 1][k - j] * C(cnt[i - 1] - 1, j - 1LL) % mod
* fact[cnt[i - 1]] % mod * infact[j] % mod) % mod;
}
}
}
ll ans = 0;
for (ll i = N; i >= 0; i--) {
ll f = ((N - i) & 1) ? -1LL : 1LL;
ans += f * dp[sz][i] % mod * fact[i] % mod;
ans = (ans % mod + mod) % mod;
}
printf("%lld\n", ans);
return 0;
}