QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#120140 | #6188. Elliptic Curve Problem | hos_lyric | AC ✓ | 1738ms | 87396kb | C++14 | 5.0kb | 2023-07-06 14:12:39 | 2023-07-06 14:12:42 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#ifndef LIBRA_OTHER_INT128_H_
#define LIBRA_OTHER_INT128_H_
#include <stdio.h>
#include <iostream>
constexpr unsigned __int128 toUInt128(const char *s) {
unsigned __int128 x = 0;
for (; *s; ++s) x = x * 10 + (*s - '0');
return x;
}
constexpr __int128 toInt128(const char *s) {
if (*s == '-') return -toInt128(s + 1);
__int128 x = 0;
for (; *s; ++s) x = x * 10 + (*s - '0');
return x;
}
unsigned __int128 inUInt128() {
static char buf[41];
scanf("%s", buf);
return toUInt128(buf);
}
__int128 inInt128() {
static char buf[41];
scanf("%s", buf);
return toInt128(buf);
}
void out(unsigned __int128 x) {
static char buf[41];
int len = 0;
do { buf[len++] = '0' + static_cast<int>(x % 10); } while (x /= 10);
for (int i = len; --i >= 0; ) putchar(buf[i]);
}
void out(__int128 x) {
if (x < 0) {
putchar('-');
out(-static_cast<unsigned __int128>(x));
} else {
out(static_cast<unsigned __int128>(x));
}
}
std::ostream &operator<<(std::ostream &os, unsigned __int128 x) {
static char buf[41];
int len = 0;
do { buf[len++] = '0' + static_cast<int>(x % 10); } while (x /= 10);
for (int i = len; --i >= 0; ) os << buf[i];
return os;
}
std::ostream &operator<<(std::ostream &os, __int128 x) {
if (x < 0) {
os << '-' << -static_cast<unsigned __int128>(x);
} else {
os << static_cast<unsigned __int128>(x);
}
return os;
}
#endif // LIBRA_OTHER_INT128_H_
using INT = __int128;
INT P, A;
INT X, Y;
INT ans;
// above
inline bool inside(INT x, INT y) {
return (P * y > x*x + A);
}
// next slope: (a/b, c/d]
void dfs(INT a, INT b, INT c, INT d) {
// cerr<<"dfs "<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
{
/*
\exists? k s.t. -(a + k c, b + k d): in
P (Y - (b + k d)) > (X - (a + k c))^2 + A
c^2 k^2 - (2 (X - a) c - P d) k + * < 0
*/
const INT numer = 2 * (X - a) * c - P * d;
const INT denom = 2 * c * c;
INT q = numer / denom, r = numer % denom;
if (r < 0) {
--q;
r += denom;
}
if (2 * r > denom) {
++q;
r -= denom;
}
const INT k = q;
if (!inside(X - (a + k * c), Y - (b + k * d))) {
return;
}
}
const INT e = a + c;
const INT f = b + d;
if (inside(X - e, Y - f)) {
dfs(a, b, e, f);
}
if (inside(X - e, Y - f)) {
/*
max k s.t. -(k e, k f): in
*/
auto check = [&](INT k) -> bool {
return inside(X - k * e, Y - k * f);
};
INT lo = 1, hi = 2;
for (; check(hi); ) {
lo = hi;
hi <<= 1;
}
for (; lo + 1 < hi; ) {
const INT mid = (lo + hi) / 2;
(check(mid) ? lo : hi) = mid;
}
const INT k = lo;
const INT XX = X - k * e;
const INT YY = Y - k * f;
// cerr<<" "<<k<<" ("<<e<<", "<<f<<"); ("<<X<<", "<<Y<<") -> ("<<XX<<", "<<YY<<")"<<endl;
ans += ((X - XX + 1) * (Y + YY + 1) - (k + 1)) / 2 - (X - XX + 1) - (YY - 1);
X = XX;
Y = YY;
}
if (inside(X - c, X - d)) {
dfs(e, f, c, d);
}
}
// \sum[0<x<=(P-1)/2] floor((x^2 + A) / P)
INT solve(INT P_, INT A_) {
P = P_;
A = A_;
// cerr<<"solve "<<P<<" "<<A<<endl;
X = (P - 1) / 2;
Y = (X*X + A) / P + 1;
ans = 0;
dfs(0, 1, 1, 0);
ans += X * (Y - 1);
return ans;
}
void stress() {
for (INT P = 3; P < 1000; P += 2) {
for (INT A = 0; A <= P; ++A) {
INT brt = 0;
for (INT x = 1; x <= (P - 1) / 2; ++x) {
brt += (x*x + A) / P;
}
const INT res = solve(P, A);
if (brt != res) {
cerr << P << " " << A << ": " << brt << " " << res << endl;
assert(false);
}
}
}
}
int main() {
// stress();
Int P, L, R;
for (; ~scanf("%lld%lld%lld", &P, &L, &R); ) {
INT ans = 0;
ans += solve(P, P - L);
ans -= solve(P, P - R - 1);
cout << ans << endl;
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3508kb
input:
11 3 8
output:
3
result:
ok 1 number(s): "3"
Test #2:
score: 0
Accepted
time: 83ms
memory: 9508kb
input:
998244353 11451400 919810000
output:
454174074
result:
ok 1 number(s): "454174074"
Test #3:
score: 0
Accepted
time: 1685ms
memory: 81036kb
input:
96311898227 25437319919 55129361817
output:
14846091352
result:
ok 1 number(s): "14846091352"
Test #4:
score: 0
Accepted
time: 1660ms
memory: 87396kb
input:
93361455259 23166562299 23393760915
output:
113606479
result:
ok 1 number(s): "113606479"
Test #5:
score: 0
Accepted
time: 1679ms
memory: 50928kb
input:
95670332497 15858139735 18812394512
output:
1477133816
result:
ok 1 number(s): "1477133816"
Test #6:
score: 0
Accepted
time: 1689ms
memory: 68336kb
input:
94221254297 78612110347 90331192055
output:
5859602618
result:
ok 1 number(s): "5859602618"
Test #7:
score: 0
Accepted
time: 1645ms
memory: 65792kb
input:
92756073587 18915851957 32881684894
output:
6982950261
result:
ok 1 number(s): "6982950261"
Test #8:
score: 0
Accepted
time: 1654ms
memory: 55008kb
input:
93651628361 3508055978 32362767220
output:
14427310592
result:
ok 1 number(s): "14427310592"
Test #9:
score: 0
Accepted
time: 1681ms
memory: 43704kb
input:
97506758381 48269906857 58513759044
output:
5121898347
result:
ok 1 number(s): "5121898347"
Test #10:
score: 0
Accepted
time: 1738ms
memory: 61104kb
input:
99954950231 20710324571 44996152988
output:
12142951150
result:
ok 1 number(s): "12142951150"
Test #11:
score: 0
Accepted
time: 1728ms
memory: 64984kb
input:
99367158071 38747300608 85189731653
output:
23221174712
result:
ok 1 number(s): "23221174712"
Test #12:
score: 0
Accepted
time: 1722ms
memory: 45344kb
input:
99936206351 6721710119 93710740278
output:
43494512281
result:
ok 1 number(s): "43494512281"