#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll N = 4e5 + 100;
const double pi = acos(-1.0);
const double eps = 1e-11;
struct dian {
ll x, y, id; double k;
}a[N], b[N];
ll n, dy[N];
double bk[N];
ll ans[N];
bool cmp(dian x, dian y) {
return x.k < y.k;
}
bool cmp1(double x, double y) {
return y - x > eps;
}
double Abs(double x) {return x < 0 ? -x : x;}
ll Abs(ll x) {return x < 0 ? -x : x;}
struct XD_tree {
ll f[N << 2], lzy[N << 2];
ll wkn[N << 2];
void up(ll now) {
f[now] = f[now << 1] + f[now << 1 | 1];
wkn[now] = wkn[now << 1] + wkn[now << 1 | 1];
}
void downa(ll now, ll l, ll r, ll x) {
lzy[now] += x;
f[now] += x * wkn[now];
}
void down(ll now, ll l, ll mid, ll r) {
if (lzy[now]) {
downa(now << 1, l, mid, lzy[now]); downa(now << 1 | 1, mid + 1, r, lzy[now]);
lzy[now] = 0;
}
}
void mark(ll now, ll l, ll r, ll pl, ll x) {
if (l == r) {
wkn[now] = 1; f[now] = x;
return ;
}
ll mid = (l + r) >> 1; down(now, l, mid, r);
if (pl <= mid) mark(now << 1, l, mid, pl, x);
else mark(now << 1 | 1, mid + 1, r, pl, x);
up(now);
}
void update(ll now, ll l, ll r, ll L, ll R, ll x) {
if (L > R) return ;
if (L <= l && r <= R) {
downa(now, l, r, x); return ;
}
ll mid = (l + r) >> 1; down(now, l, mid, r);
if (L <= mid) update(now << 1, l, mid, L, R, x);
if (mid < R) update(now << 1 | 1, mid + 1, r, L, R, x);
up(now);
}
ll query(ll now, ll l, ll r, ll L, ll R) {
if (L > R) return 0ll;
if (L <= l && r <= R) return f[now];
ll mid = (l + r) >> 1; down(now, l, mid, r); ll re = 0;
if (L <= mid) re += query(now << 1, l, mid, L, R);
if (mid < R) re += query(now << 1 | 1, mid + 1, r, L, R);
return re;
}
ll queryn(ll now, ll l, ll r, ll L, ll R) {
if (L > R) return 0;
if (L <= l && r <= R) return wkn[now];
ll mid = (l + r) >> 1; down(now, l, mid, r); ll re = 0;
if (L <= mid) re += queryn(now << 1, l, mid, L, R);
if (mid < R) re += queryn(now << 1 | 1, mid + 1, r, L, R);
return re;
}
}T;
int main() {
freopen("geometry.in", "r", stdin);
freopen("geometry.out", "w", stdout);
scanf("%lld", &n);
for (ll i = 1; i <= n; i++) {
scanf("%lld %lld", &a[i].x, &a[i].y); a[i].k = atan2(a[i].y, a[i].x); a[i].id = i; b[i] = a[i];
}
sort(b + 1, b + n + 1, cmp);
for (ll i = 1; i <= n; i++) bk[i] = b[i].k;
for (ll i = 1; i <= n; i++) dy[b[i].id] = i;
ll ans = 0;
for (ll i = 1; i <= n; i++) {
ll now = dy[i];
double k2 = a[i].k - pi; if (k2 <= -pi) k2 += 2 * pi;
ll x = lower_bound(bk + 1, bk + n + 1, k2, cmp1) - bk;
ll l = x, r = now - 1; if (l == n + 1) l = 1; if (r == 0) r = n;
if (now != x) {
if (l <= r) ans += T.query(1, 1, n, l, r), T.update(1, 1, n, l, r, 1);
else ans += T.query(1, 1, n, l, n) + T.query(1, 1, n, 1, r), T.update(1, 1, n, l, n, 1), T.update(1, 1, n, 1, r, 1);
}
k2 = a[i].k + pi; if (k2 >= pi) k2 -= 2 * pi;
x = upper_bound(bk + 1, bk + n + 1, k2, cmp1) - bk - 1;
l = now + 1, r = x; if (l == n + 1) l = 1; if (r == 0) r = n; ll num = 0;
if (now != x) {
if (l <= r) num = T.queryn(1, 1, n, l, r);
else num = T.queryn(1, 1, n, l, n) + T.queryn(1, 1, n, 1, r);
}
ans += 1ll * num * (num - 1) / 2;
T.mark(1, 1, n, now, num);
printf("%lld\n", 1ll * i * (i - 1) * (i - 2) / 6 - ans);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2022-02-07 【YBT2022寒假Day2 B】【luogu CF809D】模糊序列 / Hitchhiking in the Baltic States(平衡树优化DP)(fhq-Treap)
2022-02-07 【YBT2022寒假Day2 A】期望旅行(Dij)(期望DP)