拦截导弹(CDQ分治,DP)
很好的题,值得细细说,(果然又是个假期望).......
首先我们提取信息,显然这是个三维偏序问题
用简单的DP式子表示需要满足
f[i]=max(f[1--j]+1)(v[j]<v[i],h[j]<h[i],j<i)
那么我们发现这样可以愉快的CDQ,方案数用g数组表示,
在树状数组中注意维护就好
void add(int x,int kx,double kxx)
{
for(int i=x;i<=h_tot;i+=lowbit(i))
{
if(kx==c[i])
{
c2[i]+=kxx;
}
else if(kx>c[i])
{
c2[i]=kxx;c[i]=kx;
}
}
}
(注意这里+的方案数,是当前增加的值的方案数)
这样就结束了????
在这里才发现了CDQ优化DP的方法有些不同
我们发现普通的CDQ是将子区间处理完后,才会处理更大的区间
然而这里有一些不同的是,我们并不能一个一个小区间的处理
例如一串数 1 2 3 4 5 6
如果我们先处理左区间1-3在处理右区间4-6,在处理最后
我们发现可能的结果是1-3先更新4,5,
然后4,5更新6,显然这样是满足DP规律的
我们不妨将其看作中序遍历,先左后中后右,这样保证了正确性QAQ
注意:
这样就不能像原来一样保证序列的有序,这样我们牺牲时间
每次处理新区间时,将左右两区间按第二关键字排序一遍
然后处理完后早将这个的大区间按第一关键字排回,这样保证有序
(原来区间从下向上第一关键字当然有序,这时先大区间后小区间就要重新排了)
还有我们要两次扫,因为假设是1-n搜表示以i结尾的最大不上升序列长度
然而我们的i可能卡在中间,那么我们把区间倒转,再将每个a[i]变值(原来小的变成大的),然后只要打一遍CDQ就好了
1 #include<iostream>
2 #include<cstdio>
3 #include<string>
4 #include<algorithm>
5 #include<cmath>
6 #include<vector>
7 #include<map>
8 #include<cstring>
9 #define MAXN 510001
10 #define int long long
11 using namespace std;
12 struct node{int v,h,id;}e[MAXN];
13 int lowbit(int x){return x&(-x);}
14 bool cmp(const node &a,const node &b) {return a.id<b.id;}
15 int h_tot,v_tot;
16 int c[MAXN];
17 double c2[MAXN];
18 int dp[MAXN][3];
19 double g[MAXN][3];
20 int v_old[MAXN],h_old[MAXN];
21 int n;int maxn=0;
22 double geshu=0.0;
23 double ans[MAXN];
24 void add(int x,int kx,double kxx)
25 {
26 for(int i=x;i<=h_tot;i+=lowbit(i))
27 {
28 if(kx==c[i])
29 {
30 c2[i]+=kxx;
31 }
32 else if(kx>c[i])
33 {
34 c2[i]=kxx;c[i]=kx;
35 }
36 }
37 }
38 int query(int x)
39 {
40 int anss=0;
41 for(int i=x;i>=1;i-=lowbit(i))
42 {
43 if(c[i]>anss)
44 {
45 geshu=c2[i];anss=c[i];
46 }
47 else if(c[i]==anss)
48 {
49 geshu+=c2[i];
50 }
51 }
52 return anss;
53 }
54 void clear(int x)
55 {
56 for(int i=x;i<=h_tot;i+=lowbit(i)){c[i]=0;c2[i]=0.0;}
57 }
58 bool cmp_v(const node &a,const node &b)
59 {
60 return (a.v==b.v)?((a.h==b.h)?(a.id<b.id):a.h<b.h):(a.v<b.v);
61 }
62 void work1(int l,int r,int mid,int me)
63 {
64 sort(e+l,e+r+1,cmp_v);
65 for(int i=l;i<=r;++i)
66 {
67 if(e[i].id<=mid)
68 {
69 add(e[i].h,dp[e[i].id][me],g[e[i].id][me]);
70 }
71 else
72 {
73 geshu=0;
74 int ttt=query(e[i].h)+1;
75 if(ttt>dp[e[i].id][me])
76 {
77 dp[e[i].id][me]=ttt;
78 g[e[i].id][me]=geshu;
79 }
80 else if(ttt==dp[e[i].id][me])
81 {
82 g[e[i].id][me]+=geshu;
83 }
84 }
85 }
86 for(int i=l;i<=r;++i)
87 {
88 if(e[i].id<=mid)
89 clear(e[i].h);
90 }
91 sort(e+l,e+r+1,cmp);
92 }
93 void solve(int l,int r,int me)
94 {
95 int mid=(l+r)>>1;
96 if(l==r)return ;
97 solve(l,mid,me);
98 work1(l,r,mid,me);
99 solve(mid+1,r,me);
100 return ;
101 }
102 signed main()
103 {
104 scanf("%lld",&n);
105 for(int i=1;i<=n;++i)
106 {
107 scanf("%lld%lld",&h_old[n-i+1],&v_old[n-i+1]);
108 e[n-i+1].h=h_old[n-i+1];
109 e[n-i+1].v=v_old[n-i+1];
110 e[n-i+1].id=n-i+1;
111 }
112 sort(h_old+1,h_old+n+1);
113 sort(v_old+1,v_old+n+1);
114 h_tot=unique(h_old+1,h_old+n+1)-h_old-1;
115 v_tot=unique(v_old+1,v_old+n+1)-v_old-1;
116 for(int i=1;i<=n;++i)
117 {
118 e[i].h=lower_bound(h_old+1,h_old+h_tot+1,e[i].h)-h_old;
119 e[i].v=lower_bound(v_old+1,v_old+v_tot+1,e[i].v)-v_old;
120 }
121 for(int i=1;i<=n;++i)
122 {
123 dp[e[i].id][1]=1;dp[e[i].id][2]=1;
124 g[e[i].id][1]=1;g[e[i].id][2]=1;
125 }
126 sort(e+1,e+n+1,cmp);
127 solve(1,n,1);
128 /*for(int i=1;i<=n;++i)
129 {
130 printf("dp[%lld][1]=%lld g[%lld][1]=%lld \n",i,dp[i][1],i,g[i][1]);
131 }*/
132 for(int i=1;i<=n;++i)
133 maxn=max(maxn,dp[i][1]);
134 reverse(e+1,e+n+1);
135 for(int i=1;i<=n;++i)
136 {
137 e[i].h=h_tot-e[i].h+1;
138 e[i].v=v_tot-e[i].v+1;
139 e[i].id=i;
140 }
141 solve(1,n,2);
142 double sum=0.0;
143 for(int i=1;i<=n;++i)
144 {
145 if(dp[i][1]==maxn)sum+=g[i][1];
146 }
147 for(int i=1;i<=n;++i)
148 {
149 if(dp[n-i+1][2]+dp[i][1]-1==maxn)
150 {
151 ans[i]=(g[i][1]*g[n-i+1][2])/sum;
152 //printf("ans[%lld]=%.4lf\n",i,ans[i]);
153 }
154 else ans[i]=0.0;
155 }
156 printf("%lld\n",maxn);
157 for(int i=n;i>=1;--i)
158 {
159 printf("%.5lf ",ans[i]);
160 }
161 cout<<endl;
162 }
拦截导弹(CDQ分治,DP)的更多相关文章
- bzoj 2244: [SDOI2011]拦截导弹 cdq分治
2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec Memory Limit: 512 MBSec Special JudgeSubmit: 237 Solved: ...
- [BZOJ2244][SDOI2011]拦截导弹 CDQ分治
2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec Memory Limit: 512 MB Special Judge Description 某国为了防御敌国的导弹 ...
- BZOJ2244: [SDOI2011]拦截导弹(CDQ分治,二维LIS,计数)
Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高 ...
- BZOJ 2244: [SDOI2011]拦截导弹 (CDQ分治 三维偏序 DP)
题意 略- 分析 就是求最长不上升子序列,坐标取一下反就是求最长不下降子序列,比较大小是二维(h,v)(h,v)(h,v)的比较.我们不看概率,先看第一问怎么求最长不降子序列.设f[i]f[i]f[i ...
- BZOJ 2244: [SDOI2011]拦截导弹 [CDQ分治 树状数组]
传送门 题意:三维最长不上升子序列以及每个元素出现在最长不上升子序列的概率 $1A$了好开心 首先需要从左右各求一遍,长度就是$F[0][i]+F[1][i]-1$,次数就是$G[0][i]*G[1] ...
- BZOJ 2244 [SDOI2011]拦截导弹 ——CDQ分治
三维偏序,直接CDQ硬上. 正反两次CDQ统计结尾的方案数,最后统计即可. #include <cstdio> #include <cstring> #include < ...
- BZOJ 2225: [Spoj 2371]Another Longest Increasing (CDQ分治+dp)
题面 Description 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. Input Output ...
- luogu4849 寻找宝藏 (cdq分治+dp)
设f[i]是已经走到i号点的值. 先要给第四维离散化.然后去重 第一维排序,第二维cdq分治,第三维cdq分治,第四维树状数组,找到满足j(x,y,z,w)<=i(x,y,z,w)的j,给i统计 ...
- [BZOJ4700]适者(CDQ分治+DP/李超线段树)
如果没有秒杀,就是经典的国王游戏问题,按t/a从小到大排序即可. 考虑删除两个数i<j能给答案减少的贡献:S[i]*T[i]+P[i-1]*A[i]-A[i]+S[j]*T[j]+P[j-1]* ...
- ALGO-13_蓝桥杯_算法训练_拦截导弹(贪心,DP)
问题描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
随机推荐
- Java对象内存分布
[deerhang] 创建对象的四种方式:new关键字.反射.Object.clone().unsafe方法 new和反射是通过调用构造器创建对象的,创建对象的时候使用invokespecial指令 ...
- 微信小程序中的常见弹框
显示加载中的提示框 wx.showLoading() 当我们正在在进行网络请求时,常常就需要这个提示框 手动调用wx.hideLoading()方法才能够关闭这个提示框,通常在数据请求完毕时就应该关闭 ...
- 个人项目作业$\cdot$求交点个数
个人项目作业\(\cdot\)求交点个数 一.作业要求简介 本次作业是北航计算机学院软件工程课程的个人项目作业,个人开发能力对于软件开发团队是至关重要的,本项目旨在通过一个求几何图形的交点的需求来使学 ...
- Java Arrays.sort()重写comparator方法
先看一下接口 Arrays.sort(T[],Comparator<? super T> c); comparator要重写compare方法 compare方法大概长这样,返回值> ...
- jmeter自动停止监听--AutoStop Listener
如下图:
- 使用CSS样式的三种方法
一.内联样式 内联样式通过style属性来设置,属性值可以任意的CSS样式. 1 <!DOCTYPE html> 2 <html lang="en"> 3 ...
- 每天一个linux命令(49):at命令 atrm删除作业,由作业号标识。
atq命令 例如:从现在起三天后的下午四点运行作业at 4pm + 3 days:在July 31上午十点运行作业at 10am July 31:明天上午一点运行作业at 1am tomorrow. ...
- bashshell删除列
删除所有空白列cat yum.log | awk '{$1=$2=$3=$4=null;print $0}'>>yum.log7删除文件中的所有空格sed -i s/[[:space:]] ...
- linux服务之NTP及chrony时间同步
博客园 首页 联系 管理 linux服务之NTP及chrony时间同步 一.NTP时间同步 NTP(Network Time Protocol,网络时间协议)是由RFC 1305定义的时间同步 ...
- Sql Server 课堂笔记
创建表 --创建学生表 create table student (sno char(8) primary key, sname char(8) not null unique, ssex char( ...