zoukankan      html  css  js  c++  java
  • bzoj2244: [SDOI2011]拦截导弹

    传送门

    我tmd的连三维偏序都不会写了。。

    我tmd已经是个废宸了。。

    似乎decdq分治的bug永远是我的痛。。

    三维偏序,三维倒过来再跑一遍,看一个点前后加起来是否等于答案。

    算方案用了线段树,跑得贼慢。优秀的人都会用树状数组,不会。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<ctime>
    #include<cmath>
    const int N=5e4+7;
    typedef long long LL;
    using namespace std;
    int n,ls[N],sz,f[N],ff[N],mxans;
    double g[N],ans[N],gg[N];
    
    template<typename T> void read(T &x) {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct node {
        int x,y,ti,id;
    }p[N];
    
    bool CMP(const node&A,const node&B) {
        return A.ti<B.ti;
    }
    
    bool cmp(const node &A,const node&B) {
        return A.x>B.x||(A.x==B.x&&(A.y>B.y||(A.y==B.y&&A.ti<B.ti)));    
    }
    
    #define lc x<<1
    #define rc x<<1|1
    #define mid ((l+r)>>1)
    int mx[N<<2];
    double sum[N<<2];
    void update(int x,int l,int r,int pos,int fi,double gi) {
        if(l==r) { 
            if(mx[x]<fi) sum[x]=gi,mx[x]=fi;
            else if(mx[x]==fi) sum[x]+=gi; return;
        }
        if(pos<=mid) update(lc,l,mid,pos,fi,gi);
        else update(rc,mid+1,r,pos,fi,gi);
        mx[x]=max(mx[lc],mx[rc]);
        if(mx[lc]==mx[rc]) sum[x]=sum[lc]+sum[rc];
        else sum[x]=mx[lc]>mx[rc]?sum[lc]:sum[rc];
    }
    
    void qry(int x,int l,int r,int ql,int qr,int &f,double &g) {
        if(l>=ql&&r<=qr) {
            if(mx[x]+1>f) f=mx[x]+1,g=sum[x];
            else if(mx[x]+1==f) g+=sum[x]; return;
        }
        if(ql<=mid) qry(lc,l,mid,ql,qr,f,g);
        if(qr>mid) qry(rc,mid+1,r,ql,qr,f,g);
    }
    
    void clear_sg(int x,int l,int r) {
        if(!mx[x]) return;
        mx[x]=sum[x]=0;
        clear_sg(lc,l,mid); clear_sg(rc,mid+1,r);
    }
    
    void cdq(int l,int r,int f[],double g[]) {
        if(l>=r) return;
        cdq(l,mid,f,g);
        sort(p+l,p+r+1,cmp);
        for(int i=l;i<=r;i++) {
            if(p[i].ti<=mid) update(1,1,sz,p[i].y,f[p[i].id],g[p[i].id]);
            else qry(1,1,sz,p[i].y,sz,f[p[i].id],g[p[i].id]);
        } clear_sg(1,1,sz);
        sort(p+l,p+r+1,CMP);
        cdq(mid+1,r,f,g);
    }
    
    int main() {
        read(n);
        for(int i=1;i<=n;i++) {
            read(p[i].x); read(p[i].y); 
            p[i].ti=p[i].id=i;
            ls[++ls[0]]=p[i].y; 
            f[i]=g[i]=ff[i]=gg[i]=1;
        }    
        sort(ls+1,ls+ls[0]+1);
        sz=unique(ls+1,ls+ls[0]+1)-(ls+1);
        for(int i=1;i<=n;i++) 
            p[i].y=lower_bound(ls+1,ls+sz+1,p[i].y)-ls;
        cdq(1,n,f,g); 
        double ss=0;
        for(int i=1;i<=n;i++) {
            if(f[i]==mxans) ss+=g[i];
            else if(f[i]>mxans) ss=g[i],mxans=f[i];
        }
        printf("%d
    ",mxans);
        for(int i=1;i<=n;i++) {
            p[i].x=1e9-p[i].x+1;
            p[i].y=sz-p[i].y+1;
            p[i].ti=n-p[i].ti+1;
        }
        sort(p+1,p+n+1,CMP);
        cdq(1,n,ff,gg);
        for(int i=1;i<=n;i++) {
            int x=p[i].id;
            if(f[x]+ff[x]-1==mxans) ans[x]=g[x]*gg[x];
            else ans[x]=0;
        }
        for(int i=1;i<=n;i++) printf("%.5lf ",ans[i]/ss);
        return 0;
    }
    /*
    4
    3 30
    4 40
    6 60
    3 30
    */
    View Code
  • 相关阅读:
    《android深入探索》第七章心得
    《android深入探索》第六章心得
    《android深入探索》第五章心得
    《android深入探索》第四章心得
    《android深入探索》第三章心得
    《android深入探索》第二章心得
    嵌入式Linux的调试技术
    硬件抽象层:HAL
    让开发板发出声音:蜂鸣器驱动
    LED将为我闪烁:控制发光二极管
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8397523.html
Copyright © 2011-2022 走看看