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

    2244: [SDOI2011]拦截导弹

    Time Limit: 30 Sec  Memory Limit: 512 MBSec  Special Judge
    Submit: 954  Solved: 333
    [Submit][Status][Discuss]

    Description

    某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度、并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其拦截的导弹的飞行速度也不能大于前一发。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

    在不能拦截所有的导弹的情况下,我们当然要选择使国家损失最小、也就是拦截导弹的数量最多的方案。但是拦截导弹数量的最多的方案有可能有多个,如果有多个最优方案,那么我们会随机选取一个作为最终的拦截导弹行动蓝图。

    我方间谍已经获取了所有敌军导弹的高度和速度,你的任务是计算出在执行上述决策时,每枚导弹被拦截掉的概率。

    Input

    第一行包含一个正整数n,表示敌军导弹数量;

    下面行按顺序给出了敌军所有导弹信息:

    i+1行包含2个正整数hivi,分别表示第枚导弹的高度和速度。

    Output

    输出包含两行。

    第一行为一个正整数,表示最多能拦截掉的导弹数量;

    第二行包含n01之间的实数,第i个数字表示第i枚导弹被拦截掉的概率(你可以保留任意多位有效数字)。

    Sample Input

    4

    3 30

    4 40

    6 60

    3 30

    Sample Output

    2

    0.33333 0.33333 0.33333 1.00000

    【数据规模和约定】


    对于100%的数据,1≤n≤5*104, 1≤hi ,vi≤109;

    均匀分布着约30%的数据,所有vi均相等。

    均匀分布着约50%的数据,满足1≤hi ,vi≤1000。

    思路{

      三维偏序裸题啊。

      考场上没时间写了。。。。QAQ

    }

    #include<bits/stdc++.h>
    #define ll long long
    #define RG register
    #define il inline
    #define N 50010
    #define db double
    using namespace std;
    int n,now,sub[N],sz;
    struct dat{
      int x,y,id;
      void read(int xx){scanf("%d%d",&x,&y);id=xx;}
      bool operator <(const dat & a)const{
        return x==a.x?y<a.y:x<a.x;
      }
    }a[N];
    bool comp(const dat & a,const dat & b){
      return a.id<b.id;
    }
    bool comp1(const dat & a,const dat & b){
      return a.x>b.x;
    }
    #define lowbit(x) ((x)&(-x))
    struct node{
      int f,col;db g;
      void clear(){f=g=col=0;}
    }tr[N];
    typedef pair<int,db>pir;
    pir p[N],P[N];
    void insert(int pos,int ff,db gg){
      for(int i=pos;i<=n;i+=lowbit(i)){
        if(tr[i].col!=now)tr[i].clear(),tr[i].col=now;
        if(tr[i].f==ff)tr[i].g+=gg;
        else if(tr[i].f>ff)return;
        else tr[i].f=ff,tr[i].g=gg;
      }
    }
    pir query(int pos){
      int tempf(0);db tempg(0);
      for(int i=pos;i;i-=lowbit(i)){
        if(tr[i].col!=now)continue;
        else{
          if(tr[i].f>tempf)tempf=tr[i].f,tempg=tr[i].g;
          else if(tr[i].f==tempf)tempg+=tr[i].g;
        }
      }
      return make_pair(tempf,tempg);
    }
    pir max(pir a,pir b){
      if(a.first==b.first){a.second+=b.second;return a;}
      if(a.first>b.first)return a;
      if(a.first<b.first)return b;
    }
    void solve(int l,int r,pir pp[]){
      if(l==r){
        if(!pp[a[l].id].first)pp[a[l].id]=make_pair(1,1);
        else pp[a[l].id].first++;
        return;
      }
      int mid=(l+r)>>1;
      solve(l,mid,pp);
      sort(a+l,a+mid+1,comp1),sort(a+mid+1,a+r+1,comp1);
      ++now;int n1(l);
      for(int i=mid+1;i<=r;++i){
        while(a[n1].x>=a[i].x&&n1<=mid){
          insert(sz-a[n1].y+1,pp[a[n1].id].first,pp[a[n1].id].second);
          n1++;
        }
        pp[a[i].id]=max(query(sz-a[i].y+1),pp[a[i].id]);
      }
      sort(a+mid+1,a+r+1,comp);
      solve(mid+1,r,pp);
    }
    void solve2(int l,int r,pir pp[]){
      if(l==r){
        if(!pp[a[l].id].first)pp[a[l].id]=make_pair(1,1);
        else pp[a[l].id].first++;
        return;
      }
      int mid=(l+r)>>1;
      solve2(mid+1,r,pp);
      sort(a+l,a+mid+1),sort(a+mid+1,a+r+1);
      ++now;int n1(mid+1);
      for(int i=l;i<=mid;++i){
        while(a[n1].x<=a[i].x&&n1<=r){
          insert(a[n1].y,pp[a[n1].id].first,pp[a[n1].id].second);
          n1++;
        }
        pp[a[i].id]=max(query(a[i].y),pp[a[i].id]);
      }
      sort(a+l,a+mid+1,comp);
      solve2(l,mid,pp);
    }
    int main(){
      freopen("missile.in","r",stdin);
      freopen("missile.out","w",stdout);
      scanf("%d",&n);
      for(int i=1;i<=n;++i)a[i].read(i);
      for(int i=1;i<=n;++i)sub[i]=a[i].x;
      sort(sub+1,sub+n+1);sz=unique(sub+1,sub+n+1)-sub-1;
      for(int i=1;i<=n;++i)a[i].x=lower_bound(sub+1,sub+sz+1,a[i].x)-sub;
      for(int i=1;i<=n;++i)sub[i]=a[i].y;
      sort(sub+1,sub+n+1);sz=unique(sub+1,sub+n+1)-sub-1;
      for(int i=1;i<=n;++i)a[i].y=lower_bound(sub+1,sub+sz+1,a[i].y)-sub;
      solve(1,n,p);
      sort(a+1,a+n+1,comp);
      solve2(1,n,P);int temp(0);db ans(0);
      for(int i=1;i<=n;++i)
        temp=max(temp,p[i].first+P[i].first-1);
      printf("%d
    ",temp);
      for(int i=1;i<=n;++i)
        if(p[i].first==temp){
          ans+=p[i].second;
        }
      for(int i=1;i<=n;++i){
        if(p[i].first+P[i].first-1==temp){
          db Temp=p[i].second*P[i].second;
          printf("%.5lf ",Temp/ans);
        }else cout<<"0.00000 ";
      }
      return 0;
    }
    
  • 相关阅读:
    [转载]c++转python
    [转载]One-hot编码
    [转载]各种机器学习算法的应用场景
    SVC和SVR
    机器学习-正则化+回归与分类辨析
    C#编译时,提示缺少NuGet包
    C++中 左值和右值的区别
    C++11并发编程实战 免费书籍
    静态库和动态库
    C++中string类
  • 原文地址:https://www.cnblogs.com/zzmmm/p/8052933.html
Copyright © 2011-2022 走看看