WA 求调
查看原帖
WA 求调
324412
Filberte楼主2024/7/7 15:37

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;
}
2024/7/7 15:37
加载中...