結果
| 問題 |
No.781 円周上の格子点の数え上げ
|
| コンテスト | |
| ユーザー |
Min_25
|
| 提出日時 | 2019-09-22 18:53:56 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
CE
(最新)
AC
(最初)
|
| 実行時間 | - |
| コード長 | 4,581 bytes |
| コンパイル時間 | 705 ms |
| コンパイル使用メモリ | 87,156 KB |
| 最終ジャッジ日時 | 2024-11-14 21:40:09 |
| 合計ジャッジ時間 | 1,126 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
コンパイルメッセージ
main.cpp:108:25: error: return type 'using Array = struct std::array<long long int, 769>' {aka 'struct std::array<long long int, 769>'} is incomplete
108 | Array solve2(const i64 N) {
| ^
main.cpp: In function 'void solve2(i64)':
main.cpp:110:9: error: variable 'Array ret' has initializer but incomplete type
110 | Array ret{};
| ^~~
main.cpp: In function 'i64 solve3(i64, i64)':
main.cpp:150:8: error: 'void ans_X' has incomplete type
150 | auto ans_X = solve2(X - 1);
| ^~~~~
main.cpp:151:8: error: 'void ans_Y' has incomplete type
151 | auto ans_Y = solve2(Y);
| ^~~~~
ソースコード
#include <cstdio>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <stack>
#include <queue>
#include <tuple>
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#define _rep(_1, _2, _3, _4, name, ...) name
#define rep2(i, n) rep3(i, 0, n)
#define rep3(i, a, b) rep4(i, a, b, 1)
#define rep4(i, a, b, c) for (int i = int(a); i < int(b); i += int(c))
#define rep(...) _rep(__VA_ARGS__, rep4, rep3, rep2, _)(__VA_ARGS__)
using namespace std;
using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f80 = long double;
int get_int() {
int n, c, sign = 0;
while ((c = getchar()) < '-');
if (c == '-') sign = 1, n = 0;
else n = c - '0';
while ((c = getchar()) >= '0') n = n * 10 + c - '0';
return sign ? -n : n;
}
using i128 = __int128_t;
using u128 = __uint128_t;
inline int isqrt(i64 n) {
return sqrtl(n);
}
class PrimeCount4 {
public:
PrimeCount4(i64 N)
: sqrt_N(isqrt(N)), s1(sqrt_N + 1), s3(sqrt_N + 1),
l1(sqrt_N + 1), l3(sqrt_N + 1) {
for (int i = 1; i <= sqrt_N; ++i) s1[i] = (i - 1) >> 2;
for (int i = 1; i <= sqrt_N; ++i) l1[i] = (N / i - 1) >> 2;
for (int i = 1; i <= sqrt_N; ++i) s3[i] = (i + 1) >> 2;
for (int i = 1; i <= sqrt_N; ++i) l3[i] = (N / i + 1) >> 2;
for (int p = 3; p <= sqrt_N; p += 2) if (s1[p] + s3[p] > s1[p - 1] + s3[p - 1]) {
const i64 M = N / p, q = i64(p) * p;
const int w = sqrt_N / p, v = min<i64>(sqrt_N, N / q);
auto update = [&] (vector<int>& ds1, vector<int>& ds3,
vector<i64>& dl1, vector<i64>& dl3) -> void {
const int p1 = s1[p - 1];
const int p3 = s3[p - 1];
for (int i = 1; i <= w; ++i) {
dl1[i] -= l1[i * p] - p1;
dl3[i] -= l3[i * p] - p3;
}
const int t = min(isqrt(M), v);
for (int i = w + 1; i <= t; ++i) {
dl1[i] -= s1[M / i] - p1;
dl3[i] -= s3[M / i] - p3;
}
for (int i = t + 1, q = M / i, r = M % i, c1 = s1[q] - p1, c3 = s3[q] - p3; i <= v; ++i, r -= q) {
if (r < 0) r += i, --q, c1 = s1[q] - p1, c3 = s3[q] - p3;
dl1[i] -= c1;
dl3[i] -= c3;
}
for (int j = sqrt_N / p; j >= p; --j) {
const int c1 = s1[j] - p1;
const int c3 = s3[j] - p3;
for (int i = j * p, e = min(sqrt_N + 1, (j + 1) * p); i < e; ++i) {
ds1[i] -= c1;
ds3[i] -= c3;
}
}
};
if ((p & 3) == 1) {
update(s1, s3, l1, l3);
} else {
update(s3, s1, l3, l1);
}
}
}
private:
const int sqrt_N;
public:
vector<int> s1, s3;
vector<i64> l1, l3;
};
const int T = 768; // N <= 1e14
using Array = array<i64, T + 1>;
Array solve2(const i64 N) {
assert(N <= i64(1e14));
Array ret{};
if (N >= 1) {
auto pc = PrimeCount4(N);
const int sqrt_N = isqrt(N);
vector<int> primes;
for (int i = 3; i <= sqrt_N; ++i) if (pc.s1[i] + pc.s3[i] > pc.s1[i - 1] + pc.s3[i - 1]) {
primes.push_back(i);
}
primes.push_back(sqrt_N + 1);
function< void(i64, int, int) > rec = [&] (i64 n, int beg, int coeff) -> void {
const int below = primes[beg] - 1;
ret[2 * coeff] += (n > sqrt_N ? pc.l1[N / n] : pc.s1[n]) - pc.s1[below];
for (int pi = beg; pi < int(primes.size()); ++pi) {
int p = primes[pi];
if (i64(p) * p > n) break;
i64 nn = n / p;
if ((p & 3) == 1) {
for (int e = 2; nn >= p; ) {
rec(nn, pi + 1, coeff * e); e += 1;
ret[coeff * e] += 1;
nn /= p;
}
} else {
while (nn >= p) {
nn /= p;
ret[coeff] += 1;
if (nn < p) break;
rec(nn, pi + 1, coeff);
nn /= p;
}
}
}
};
for (i64 n = N; n >= 1; n >>= 1) rec(n, 0, 1), ret[1] += 1;
}
return ret;
}
i64 solve3(i64 X, i64 Y) {
auto ans_X = solve2(X - 1);
auto ans_Y = solve2(Y);
i64 ans = 0;
for (int i = T; i >= 0; --i) {
if (ans_Y[i] > ans_X[i]) {
ans = i;
break;
}
}
return 4 * ans;
}
void solve() {
i64 X, Y;
while (~scanf("%lld %lld", &X, &Y)) {
i64 ans = solve3(X, Y);
printf("%lld\n", ans);
}
}
int main() {
clock_t beg = clock();
solve();
clock_t end = clock();
fprintf(stderr, "%.3f sec\n", double(end - beg) / CLOCKS_PER_SEC);
return 0;
}
Min_25