結果
| 問題 | No.1144 Triangles |
| コンテスト | |
| ユーザー |
fastmath
|
| 提出日時 | 2020-07-31 22:55:59 |
| 言語 | C++17(clang) (17.0.6 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,793 bytes |
| コンパイル時間 | 1,973 ms |
| コンパイル使用メモリ | 165,088 KB |
| 実行使用メモリ | 127,968 KB |
| 最終ジャッジ日時 | 2024-07-06 20:28:13 |
| 合計ジャッジ時間 | 11,344 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 23 WA * 2 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define double long double
#define ii pair <int, int>
#define app push_back
#define all(a) a.begin(), a.end()
#define bp __builtin_popcount
#define ll long long
const int N = 2007, C = 1e4 + 7, MOD = 1000 * 1000 * 1000 + 7;
int mod(int n) {
n %= MOD;
if (n < 0) return n + MOD;
else return n;
}
int fp(int a, int p) {
int ans = 1, c = a;
for (int i = 0; (1ll << i) <= p; ++i) {
if ((p >> i) & 1) ans = mod(ans * c);
c = mod(c * c);
}
return ans;
}
int dv(int a, int b) { return mod(a * fp(b, MOD - 2)); }
int n, ans = 0;
struct Point {
int x, y;
bool operator < (Point p) { return (y < p.y) || (y == p.y && x > p.x); }
} a[N];
int cp(int x1, int y1, int x2, int y2) { return x1 * y2 - y1 * x2; }
struct Line {
int x, y, i, j;
bool operator < (Line l) {
int t = cp(x, y, l.x, l.y);
return t > 0 || (t == 0 && i < l.i) || (t == 0 && i == l.i && j < l.j);
}
};
struct Fen {
int f[N];
void clear() {
for (int i = 0; i < N; ++i) f[i] = 0;
}
void add(int i, int x) {
for (; i < N; i |= i + 1)
f[i] += x;
}
int get(int i) {
int ans = 0;
for (; i >= 0; i &= i + 1, --i) ans += f[i];
return ans;
}
int get(int l, int r) {
return get(r) - get(l - 1);
}
} fx, fy;
int pos[N];
Point ord[N];
signed main() {
#ifdef HOME
freopen("input.txt", "r", stdin);
#else
ios_base::sync_with_stdio(0); cin.tie(0);
#endif
cin >> n; for (int i = 0; i < n; ++i) { cin >> a[i].x >> a[i].y; a[i].x += C; a[i].y += C; }
sort(a, a + n);
for (int i = 0; i < n; ++i)
ord[i] = a[i];
vector <Line> l;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
l.app({a[j].x - a[i].x, a[j].y - a[i].y, i, j});
}
}
for (int i = 0; i < n; ++i) pos[i] = i;
sort(all(l));
int ptr = 0;
for (int i = 0; i < n; ++i) {
fx.add(i, a[i].x);
fy.add(i, a[i].y);
}
auto add = [&] (int &a, int b) {
a = mod(a + b);
};
while (ptr < l.size()) {
int t = ptr;
vector <Line> mem;
while (ptr < l.size() && cp(l[t].x, l[t].y, l[ptr].x, l[ptr].y) == 0) {
auto &e = l[ptr];
mem.app(e);
swap(pos[e.i], pos[e.j]);
fx.add(pos[e.i], ord[pos[e.j]].x-ord[pos[e.i]].x);
fy.add(pos[e.i], ord[pos[e.j]].y-ord[pos[e.i]].y);
fx.add(pos[e.j], ord[pos[e.i]].x-ord[pos[e.j]].x);
fy.add(pos[e.j], ord[pos[e.i]].y-ord[pos[e.j]].y);
swap(ord[pos[e.i]], ord[pos[e.j]]);
++ptr;
}
for (auto e : mem) {
int j = e.i, k = e.j;
int C = a[j].x * a[k].y - a[j].y * a[k].x;
int A = (a[j].y - a[k].y);
int B = (a[k].x - a[j].x);
if (n <= 500) {
for (int i = 0; i + 1 < n; ++i)
assert(ord[i].x * A + ord[i].y * B <= ord[i+1].x * A + ord[i+1].y * B);
}
int l = -1, r = n;
while (l < r - 1) {
int m = (l + r) >> 1;
if (C + ord[m].x * A + ord[m].y * B < 0)
l = m;
else
r = m;
}
int lx = fx.get(l);
int ly = fy.get(l);
A = mod(A);
B = mod(B);
C = mod(C);
add(ans, -C * (l + 1));
add(ans, -A * lx);
add(ans, -B * ly);
add(ans, C * (n - l - 1));
add(ans, A * (fx.get(n) - lx));
add(ans, B * (fy.get(n) - ly));
assert(ans >= 0);
}
}
cout << dv(ans, 3) << '\n';
}
fastmath