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

    cdq。。还真是。。

    一开始自己写,设f[i]为以i结尾的最优方案,fn[i]为以i结尾的最优方案数,然后cdq完了第一问就出来了,还顺便把总最优方案数算了,

    and then? mengbier

    然后各路%啊,一个下午+一晚上就交代了

    怎么做呢?我们再cdq出另一个f和fn表示以i开头的最优方案和方案数

    然后想一想i在这 l——————i——————r

    然后 f[0][i]就是l~i的最优方案了,f[1][i]就是i~r的最优方案

    那么两个一合并,再减去重复计算的i位置,假如等于最优方案,说明i出现了fn[0][i]*fn[1][i](一一组合嘛)

    完成。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long double LD;
    
    int n;
    
    int s[51000];LD g[51000];
    int lowbit(int x){return x&-x;}
    void change(int x,int k,LD fan)
    {
        while(x<=50500)
        {
            if(s[x]<k)
            {
                s[x]=k;
                g[x]=fan;
            }
            else if(s[x]==k)g[x]+=fan;
            x+=lowbit(x);
        }
    }
    void clean(int x)
    {
        while(x<=50500)
        {
            s[x]=0;g[x]=0;
            x+=lowbit(x);
        }
    }
    int getmax(int x,LD &fan)
    {
        int ret=0;fan=0;
        while(x>=1)
        {
            if(s[x]>ret)
            {
                ret=s[x];
                fan=g[x];
            }
            else if(s[x]==ret)fan+=g[x];
            x-=lowbit(x);
        }
        return ret;
    }
    
    struct node
    {
        int x,y,z;
    }a[51000],b[51000];
    bool cmpx(node n1,node n2){return n1.x<n2.x;}
    bool cmpx2(node n1,node n2){return n1.x>n2.x;}
    bool cmpy(node n1,node n2){return n1.y>n2.y;}
    bool cmpy2(node n1,node n2){return n1.y<n2.y;}
    int lslen,ls[51000];
    void LSH()
    {
        lslen=0;
        for(int i=1;i<=n;i++)ls[++lslen]=a[i].y;
        sort(ls+1,ls+lslen+1);
        lslen=unique(ls+1,ls+lslen+1)-ls-1;
        for(int i=1;i<=n;i++)
            a[i].y=lower_bound(ls+1,ls+lslen+1,a[i].y)-ls;
            
        lslen=0;
        for(int i=1;i<=n;i++)ls[++lslen]=a[i].z;
        sort(ls+1,ls+lslen+1);
        lslen=unique(ls+1,ls+lslen+1)-ls-1;
        for(int i=1;i<=n;i++)
            a[i].z=lower_bound(ls+1,ls+lslen+1,a[i].z)-ls, a[i].z=n-a[i].z+1;
    }
    
    int f[2][51000];LD fn[2][51000];
    void cdq(int l,int r)
    {
        if(l==r)return ;
        int mid=(l+r)/2;
        
        cdq(l,mid);
        
        
        sort(a+mid+1,a+r+1,cmpy);
        int tp=l;
        for(int i=mid+1;i<=r;i++)
        {
            while(tp<=mid&&(a[tp].y>=a[i].y))
                change(a[tp].z,f[0][a[tp].x],fn[0][a[tp].x]), tp++;
            LD fan;
            int d=getmax(a[i].z,fan)+1;
            if(d>f[0][a[i].x])
            {
                f[0][a[i].x]=d;
                fn[0][a[i].x]=fan;
            }
            else if(d==f[0][a[i].x])fn[0][a[i].x]+=fan;
        }
        for(int i=l;i<=mid;i++)clean(a[i].z);
        sort(a+mid+1,a+r+1,cmpx);
        
        
        cdq(mid+1,r);
        
        sort(a+l,a+r+1,cmpy);
    }
    void cdq2(int l,int r)
    {
        if(l==r)return ;
        int mid=(l+r)/2;
        
        cdq2(l,mid);
        
        
        sort(a+mid+1,a+r+1,cmpy2);
        int tp=l;
        for(int i=mid+1;i<=r;i++)
        {
            while(tp<=mid&&a[tp].y<=a[i].y)
                change(a[tp].z,f[1][a[tp].x],fn[1][a[tp].x]), tp++;
            LD fan;
            int d=getmax(a[i].z,fan)+1;
            if(d>f[1][a[i].x])
            {
                f[1][a[i].x]=d;
                fn[1][a[i].x]=fan;
            }
            else if(d==f[1][a[i].x])fn[1][a[i].x]+=fan;
        }
        for(int i=l;i<=mid;i++)clean(a[i].z);
        sort(a+mid+1,a+r+1,cmpx2);
        
        
        cdq2(mid+1,r);
        
        sort(a+l,a+r+1,cmpy2);
    }
    
    
    LD cao[51000];
    int main()
    {
        freopen("missile.in","r",stdin);
        freopen("missile.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            a[i].x=i, scanf("%d%d",&a[i].y,&a[i].z);
        LSH();
        for(int i=1;i<=n;i++)b[i]=a[i];
        
        
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++)f[0][i]=1,fn[0][i]=1;
        cdq(1,n);
        int mmax=0;LD sum=0;
        for(int i=1;i<=n;i++)
            if(f[0][i]>mmax)
            {
                mmax=f[0][i];
                sum=fn[0][i];
            }
            else if(mmax==f[0][i])sum+=fn[0][i];
        printf("%d
    ",mmax);
        
        
        for(int i=1;i<=n;i++)a[i]=b[n-i+1];
        for(int i=1;i<=n;i++)a[i].z=n-a[i].z+1;
        for(int i=1;i<=n;i++)f[1][i]=1,fn[1][i]=1;
        cdq2(1,n);
        
        
        for(int i=1;i<=n;i++)
            if(f[0][i]+f[1][i]-1==mmax)
                cao[i]=fn[0][i]*fn[1][i];
        for(int i=1;i<n;i++)printf("%.5Lf ",cao[i]/sum);
        printf("%.5Lf
    ",cao[n]/sum);
        return 0;
    }
  • 相关阅读:
    东芝线阵CCD芯片TCD1305DG驱动时序设计
    数字电路中应避免产生不必要的锁存器 Latch
    准双向口、开漏输出、推挽输出结构介绍
    边沿检测电路小结
    数字系统中的亚稳态及其解决办法
    launch edge 和 latch edge 延迟
    基于Verilog的偶数、奇数、半整数分频以及任意分频器设计
    找到了救命的东西 NVIDIA MPS (multi-process service)
    关于多个程序同时launch kernels on the same GPU
    java的System.currentTimeMillis()和System.nanoTime()
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8661574.html
Copyright © 2011-2022 走看看