Description
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度、并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其拦截的导弹的飞行速度也不能大于前一发。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
在不能拦截所有的导弹的情况下,我们当然要选择使国家损失最小、也就是拦截导弹的数量最多的方案。但是拦截导弹数量的最多的方案有可能有多个,如果有多个最优方案,那么我们会随机选取一个作为最终的拦截导弹行动蓝图。
我方间谍已经获取了所有敌军导弹的高度和速度,你的任务是计算出在执行上述决策时,每枚导弹被拦截掉的概率。
Input
第一行包含一个正整数n,表示敌军导弹数量;
下面 行按顺序给出了敌军所有导弹信息:
第i+1行包含2个正整数hi和vi,分别表示第 枚导弹的高度和速度。
Output
输出包含两行。
第一行为一个正整数,表示最多能拦截掉的导弹数量;
第二行包含n个0到1之间的实数,第i个数字表示第i枚导弹被拦截掉的概率(你可以保留任意多位有效数字)。
Sample Input
4
3 30
4 40
6 60
3 30
3 30
4 40
6 60
3 30
Sample Output
2
0.33333 0.33333 0.33333 1.00000
0.33333 0.33333 0.33333 1.00000
解题思路:
让我想起了前一阵学弟们做的题(手动滑稽)
这道题第一问相当于一个二维LIS。
主要是第二问,我们只需统计有多少最大的答案,和节点在多少方案中,最后相除即可。
最长的只需枚举统计就好了。
而节点在多少方案中可以统计其最长前缀LIS和最长后缀LIS,如果相加等于答案+1那么就合法。
相当于最长前缀LIS数量*最长后缀LIS数量。
这个可以用结构体重载运算符实现。
最后中间运算变量可能>1020中间变量要用double,因为double不会爆而是牺牲精度。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll spc<<1 5 #define rrr spc<<1|1 6 const int N=200000; 7 const int M=1000000; 8 struct trnt{ 9 int maxv; 10 double maxt; 11 }tr[M],strnt; 12 struct data{ 13 int t; 14 int h; 15 int tv; 16 int v; 17 }d[N]; 18 int n; 19 int tot; 20 int cnt; 21 double sum; 22 trnt f[N],g[N]; 23 bool cmpb(data a,data b){return a.t<b.t;} 24 bool cmph(data a,data b){return a.h>b.h;} 25 bool cmpv(data a,data b){return a.tv<b.tv;} 26 trnt max(trnt x,trnt y) 27 { 28 trnt ans; 29 if(x.maxv<y.maxv) 30 ans=y; 31 else if(x.maxv>y.maxv) 32 ans=x; 33 else 34 ans=(trnt){x.maxv,x.maxt+y.maxt}; 35 return ans; 36 } 37 void pushup(int spc) 38 { 39 tr[spc]=max(tr[lll],tr[rrr]); 40 return ; 41 } 42 void update(int l,int r,int pos,int spc,int v,double t) 43 { 44 if(l==r) 45 { 46 if(v==-1) 47 tr[spc]=strnt; 48 else{ 49 if(tr[spc].maxv<v) 50 tr[spc]=(trnt){v,t}; 51 else if(tr[spc].maxv==v) 52 tr[spc].maxt+=t; 53 } 54 return ; 55 } 56 int mid=(l+r)>>1; 57 if(pos<=mid) 58 update(l,mid,pos,lll,v,t); 59 else 60 update(mid+1,r,pos,rrr,v,t); 61 pushup(spc); 62 return ; 63 } 64 trnt query(int ll,int rr,int l,int r,int spc) 65 { 66 if(ll>r||l>rr) 67 return strnt; 68 if(ll<=l&&r<=rr) 69 return tr[spc]; 70 int mid=(l+r)>>1; 71 return max(query(ll,rr,l,mid,lll),query(ll,rr,mid+1,r,rrr)); 72 } 73 void CDQ(int l,int r) 74 { 75 if(l==r) 76 return ; 77 int mid=(l+r)>>1; 78 CDQ(l,mid); 79 std::sort(d+l,d+mid+1,cmph); 80 std::sort(d+mid+1,d+r+1,cmph); 81 int j=l; 82 for(int i=mid+1;i<=r;i++) 83 { 84 for(;j<=mid&&d[j].h>=d[i].h;j++) 85 update(1,n,d[j].v,1,f[d[j].t].maxv,f[d[j].t].maxt); 86 trnt tmp=query(d[i].v,n,1,n,1); 87 tmp.maxv++; 88 f[d[i].t]=max(f[d[i].t],tmp); 89 } 90 for(int i=l;i<j;i++) 91 update(1,n,d[i].v,1,-1,0); 92 std::sort(d+mid+1,d+r+1,cmpb); 93 CDQ(mid+1,r); 94 return ; 95 } 96 void Dark_CDQ(int l,int r) 97 { 98 if(l==r) 99 return ; 100 int mid=(l+r)>>1; 101 Dark_CDQ(mid+1,r); 102 std::sort(d+l,d+mid+1,cmph); 103 std::sort(d+mid+1,d+r+1,cmph); 104 int j=r; 105 for(int i=mid;i>=l;i--) 106 { 107 for(;j>=mid+1&&d[j].h<=d[i].h;j--) 108 update(1,n,d[j].v,1,g[d[j].t].maxv,g[d[j].t].maxt); 109 trnt tmp=query(1,d[i].v,1,n,1); 110 tmp.maxv++; 111 g[d[i].t]=max(g[d[i].t],tmp); 112 } 113 for(int i=r;i>j;i--) 114 update(1,n,d[i].v,1,-1,0); 115 std::sort(d+l,d+mid+1,cmpb); 116 Dark_CDQ(l,mid); 117 return ; 118 } 119 int main() 120 { 121 scanf("%d",&n); 122 for(int i=1;i<=n;i++) 123 { 124 scanf("%d%d",&d[i].h,&d[i].tv); 125 d[i].t=i; 126 } 127 std::sort(d+1,d+n+1,cmpv); 128 tot++; 129 d[1].v=1; 130 for(int i=2;i<=n;i++) 131 { 132 if(d[i].tv!=d[i-1].tv) 133 tot++; 134 d[i].v=tot; 135 } 136 std::sort(d+1,d+n+1,cmpb); 137 for(int i=1;i<=n;i++) 138 f[i]=g[i]=(trnt){1,1}; 139 CDQ(1,n); 140 trnt ans=strnt; 141 for(int i=1;i<=n;i++) 142 ans=max(ans,f[i]); 143 printf("%d ",ans.maxv); 144 for(int i=1;i<=n;i++) 145 if(f[i].maxv==ans.maxv) 146 sum+=(double)(f[i].maxt); 147 std::sort(d+1,d+n+1,cmpb); 148 Dark_CDQ(1,n); 149 std::sort(d+1,d+n+1,cmpb); 150 for(int i=1;i<=n;i++) 151 { 152 if(g[i].maxv+f[i].maxv-1==ans.maxv) 153 printf("%.5lf ",(double)(f[i].maxt)*(double)(g[i].maxt)/sum); 154 else 155 printf("0.00000 "); 156 } 157 puts(""); 158 return 0; 159 }