cdq分治,80pts,WA了四个点,但个人感觉没有精度问题。求大佬看看
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 100;
int n;
struct Pt{
int a, b, id;
}p[N];
struct State{
int len;__float128 met;
friend State operator ^ (State x, State y){
if(x.len > y.len) return x;
if(x.len < y.len) return y;
return (State){x.len, x.met + y.met};
}
}f[N], g[N];
struct SegMent_Tree{
State t[N << 2];
bool tg[N << 2];
void init(){t[1] = (State){-1, 0};tg[1] = 1;}
void ck(int u, int l, int r){
if(!tg[u]) return ;
tg[u << 1] = tg[u << 1 | 1] = 1;
t[u << 1] = t[u << 1 | 1] = (State){-1, 0};
tg[u] = 0;
}
void push_up(int u){t[u] = t[u << 1] ^ t[u << 1 | 1];}
void add(int u, int l, int r, int x, State val){
ck(u, l, r);
if(l == r){t[u] = t[u] ^ val;return ;}
int mid = (l + r) >> 1;
if(x <= mid) add(u << 1, l, mid, x, val);
else add(u << 1 | 1, mid + 1, r, x, val);
push_up(u);
}
State qry(int u, int l, int r, int L, int R){
ck(u, l, r);
if(L <= l && r <= R) return t[u];
int mid = (l + r) >> 1;
if(R <= mid) return qry(u << 1, l, mid, L, R);
if(L > mid) return qry(u << 1 | 1, mid + 1, r, L, R);
return qry(u << 1, l, mid, L, R) ^ qry(u << 1 | 1, mid + 1, r, L , R);
}
}T;
bool cmp1(Pt x, Pt y){return x.id < y.id;}
bool cmp2(Pt x, Pt y){return x.a > y.a;}
bool cmp3(Pt x, Pt y){return x.id > y.id;}
bool cmp4(Pt x, Pt y){return x.a < y.a;}
void cdq1(int l, int r){
if(l == r) return ;
int mid = (l + r) >> 1;
sort(p + l, p + r + 1, cmp1);
cdq1(l, mid);
sort(p + l, p + mid + 1, cmp2);
sort(p + mid + 1, p + r + 1, cmp2);
T.init();
//cout << l << "~" << r << " ";puts("Begin");
for(int pl = l, pr = mid + 1;pr <= r;pr++){
for(;pl <= mid && p[pl].a >= p[pr].a;pl++){
T.add(1, 1, n, p[pl].b, f[p[pl].id]);
//printf("Add: id = %d, p = %d, Length = %d, Times = %.0lf\n",p[pl].id,p[pl].b, f[p[pl].id].len, f[p[pl].id].met);
}
//printf("Qry: %d to %d\n",p[pr].b, n);
State cur = T.qry(1, 1, n, p[pr].b, n);
//printf("Get Max = %d Method = %.0lf\n",cur.len,cur.met);
cur.len++;
//printf("Now f[%d] = {%d,%.0lf}\n",p[pr].id,f[p[pr].id].len,f[p[pr].id].met);
f[p[pr].id] = f[p[pr].id] ^ cur;
//printf("After f[%d] = {%d,%.0lf}\n",p[pr].id,f[p[pr].id].len,f[p[pr].id].met);
}
//puts("End");puts("");
cdq1(mid + 1, r);
}
void cdq2(int l, int r){
if(l == r) return ;
int mid = (l + r) >> 1;
sort(p + l, p + r + 1, cmp3);
cdq2(l, mid);
sort(p + l, p + mid + 1, cmp4);
sort(p + mid + 1, p + r + 1, cmp4);
T.init();
for(int pl = l, pr = mid + 1;pr <= r;pr++){
for(;pl <= mid && p[pl].a <= p[pr].a;pl++){
T.add(1, 1, n, p[pl].b, g[p[pl].id]);
}
State cur = T.qry(1, 1, n, 1, p[pr].b);
cur.len++;
g[p[pr].id] = g[p[pr].id] ^ cur;
}
cdq2(mid + 1, r);
}
int lsh[N], lsn;
void pre(){
for(int i = 1;i <= n;i++) lsh[i] = p[i].a;
sort(lsh + 1, lsh + 1 + n);
lsn = unique(lsh + 1, lsh + 1 + n) - lsh - 1;
for(int i = 1;i <= n;i++) p[i].a = lower_bound(lsh + 1, lsh + 1 + lsn, p[i].a) - lsh;
for(int i = 1;i <= n;i++) lsh[i] = p[i].b;
sort(lsh + 1, lsh + 1 + n);
lsn = unique(lsh + 1, lsh + 1 + n) - lsh - 1;
for(int i = 1;i <= n;i++) p[i].b = lower_bound(lsh + 1, lsh + 1 + lsn, p[i].b) - lsh;
}
__float128 ans[N];
int main(){
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%d%d",&p[i].a,&p[i].b);
p[i].id = i;
f[i] = g[i] = (State){1, 1.0};
}
pre();
cdq1(1, n);
cdq2(1, n);
int lgst = 1;
for(int i = 1;i <= n;i++) lgst = max(lgst, f[i].len + g[i].len - 1);
printf("%d\n",lgst);
__float128 Mt = 0;
for(int i = 1;i <= n;i++) if(f[i].len == lgst) Mt += f[i].met;
for(int i = 1;i <= n;i++){
if(f[i].len + g[i].len - 1 != lgst) ans[i] = 0;
else ans[i] = f[i].met * g[i].met / Mt;
}
for(int i = 1;i <= n;i++){
double op = ans[i];
printf("%.4lf ", op);
}
return 0;
}