結果
| 問題 |
No.1999 Lattice Teleportation
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-03-22 12:41:15 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 80 ms / 2,000 ms |
| コード長 | 3,636 bytes |
| コンパイル時間 | 2,060 ms |
| コンパイル使用メモリ | 120,496 KB |
| 実行使用メモリ | 18,864 KB |
| 最終ジャッジ日時 | 2024-11-08 11:08:09 |
| 合計ジャッジ時間 | 4,030 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 29 |
ソースコード
#include <cassert>
#include <cstdio>
#include <cinttypes>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
class strictInput
{
char *p;
off_t cur = 0;
off_t len = 0;
public:
explicit strictInput(int fd = 0)
{
struct stat st;
fstat(fd, &st);
p = (char *)mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
len = st.st_size;
}
char readChar()
{
assert(cur != len);
return p[cur++];
}
void unreadChar()
{
assert(cur != 0);
--cur;
}
bool isEOF() { return cur == len; }
void readEOF() { assert(isEOF()); }
void readSpace() { assert(readChar() == ' '); }
void readEoln() { assert(readChar() == '\n'); }
// reads uint64_t in range [from, to]
uint64_t readU64(uint64_t from = 0, uint64_t to = UINT64_MAX)
{
uint64_t cur = 0;
off_t read_cnt = 0;
bool leading_zero = false;
while (!isEOF())
{
char p = readChar();
if (!('0' <= p && p <= '9'))
{
unreadChar();
break;
}
uint64_t v = p - '0';
assert(cur <= UINT64_MAX / 10);
cur *= 10;
assert(cur <= UINT64_MAX - v);
cur += v;
if (read_cnt == 0 && v == 0)
leading_zero = true;
++read_cnt;
}
if (cur == 0)
assert(read_cnt == 1);
else
assert(!leading_zero);
return cur;
}
// reads int64_t in range [from, to]
int64_t readI64(int64_t from = INT64_MIN, int64_t to = INT64_MAX)
{
uint64_t cur = 0;
off_t read_cnt = 0;
bool leading_zero = false;
bool leading_minus = readChar() == '-';
if (!leading_minus)
unreadChar();
while (!isEOF())
{
char p = readChar();
if (!('0' <= p && p <= '9'))
{
unreadChar();
break;
}
uint64_t v = p - '0';
assert(cur <= UINT64_MAX / 10);
cur *= 10;
assert(cur <= UINT64_MAX - v);
cur += v;
if (read_cnt == 0 && v == 0)
leading_zero = true;
++read_cnt;
}
if (cur == 0)
assert(read_cnt == 1 && !leading_minus);
else
assert(!leading_zero);
if (cur <= INT64_MAX)
{
int64_t ret = cur;
if (leading_minus)
ret = -ret;
return ret;
}
else
{
assert(leading_minus && cur == uint64_t(INT64_MIN));
return INT64_MIN;
}
}
};
#include <algorithm>
#include <iostream>
#include <numeric>
#include <tuple>
#include <vector>
using namespace std;
int main()
{
strictInput Inp;
int N;
N = Inp.readI64(1, 100'000);
Inp.readEoln();
vector<tuple<long long, long long, long long, long long>> ev;
vector<pair<long long, long long>> pts;
for (int i = 0; i < N; ++i)
{
long long a, b;
a = Inp.readI64(-1'000'000'000, 1'000'000'000);
Inp.readSpace();
b = Inp.readI64(-1'000'000'000, 1'000'000'000);
Inp.readEoln();
if (a == 0 && b == 0)
continue;
ev.emplace_back(-b, a, a, b);
ev.emplace_back(b, -a, -a, -b);
}
Inp.readEOF();
sort(ev.begin(), ev.end(), [&](auto a, auto b)
{
auto [ax, ay, a1, a2] = a;
auto [bx, by, b1, b2] = b;
bool ar = make_pair(ax, ay) > make_pair(0LL, 0LL);
bool br = make_pair(bx, by) > make_pair(0LL, 0LL);
if(ar!=br) return br;
return ax*by > bx*ay; });
long long x = 0, y = 0;
for (auto [xe, ye, v1, v2] : ev)
{
x += v1;
y += v2;
pts.emplace_back(x, y);
}
const int MOD = 1e9 + 7;
long long A = 0, B = 0;
for (int i = 0; i < (int)pts.size(); ++i)
{
int j = (i + 1) % (int)pts.size();
auto [ax, ay] = pts[i];
auto [bx, by] = pts[j];
A = (A + ((ax % MOD) * (by % MOD)) - ((bx % MOD) * (ay % MOD))) % MOD;
B = (B + gcd(abs(ax - bx), abs(ay - by))) % MOD;
}
if (A < 0)
A += MOD;
if (A % 2 == 1)
A += MOD;
A /= 2;
long long hB = B;
if (hB < 0)
hB += MOD;
if (hB % 2 == 1)
hB += MOD;
hB /= 2;
long long ans = (A + hB + 1) % MOD;
cout << ans << endl;
}