BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化)

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #define MAXN 50010
 6 #define LL long long
 7 using namespace std;
 8 struct ddd
 9 {
10     int t,h,v,ans;
11     #define t(x) a[x].t
12     #define h(x) a[x].h
13     #define v(x) a[x].v
14     #define ans(x) a[x].ans
15 }a[MAXN];
16 int n,th[MAXN],tv[MAXN];
17 bool cmp1(ddd a,ddd b){return a.t==b.t?(a.h==b.h?(a.v<b.v):a.h<b.h):a.t<b.t;}
18 bool cmp2(ddd a,ddd b){return a.h==b.h?(a.t==b.t?(a.v>b.v):a.t<b.t):a.h>b.h;}
19 int ans=1;
20 int C[MAXN];
21 #define lowbit(x) ((x)&(-(x)))
22 //void add(int x,int y){while(x<=n){C[x]+=y;x+=lowbit(x);}}
23 //int ask(int x){int ans=0;while(x){ans+=C[x];x-=lowbit(x);}return ans;}
24 void add(int x,int y)
25 {//cout<<"add "<<x<<" "<<y<<endl;
26 while(x){C[x]=max(C[x],y);x-=lowbit(x);}}
27 void admin(int x,int y)
28 {while(x){C[x]=min(C[x],y);x-=lowbit(x);}}
29 int ask(int x){int ans=0;while(x<=n){ans=max(ans,C[x]);x+=lowbit(x);}return ans;}
30 void CDQ(int l,int r)
31 {
32     if(l==r){return;}
33     int mid=(l+r)>>1;
34 //    sort(a+l,a+mid+1,cmp1);
35     CDQ(l,mid);
36     sort(a+l,a+mid+1,cmp2);
37     sort(a+mid+1,a+r+1,cmp2);
38     int j=l;
39 //    cout<<"# "<<l<<" "<<r<<endl;
40 //    for(int i=l;i<=r;i++)cout<<i<<": "<<t(i)<<" "<<h(i)<<" "<<v(i)<<endl;
41     for(int i=mid+1;i<=r;i++)
42     {
43         while(j<=mid&&h(j)>=h(i)){//cout<<"!!!!!!!!j "<<j<<" "<<ans(j)<<endl;
44         add(v(j),ans(j)),j++;}
45         ans(i)=max(ans(i),ask(v(i))+1);//cout<<"!!!!!!!!!!ans "<<i<<" "<<ans(i)<<endl;
46     }
47     for(int i=l;i<j;i++)admin(v(i),0);
48     sort(a+mid+1,a+r+1,cmp1);
49     CDQ(mid+1,r);
50 }
51 signed main()
52 {
53 //    freopen("in.txt","r",stdin);
54
55     cin>>n;
56     for(int i=1;i<=n;i++)
57         cin>>h(i)>>v(i),t(i)=i,th[i]=h(i),tv[i]=v(i);
58     sort(th+1,th+n+1);
59     sort(tv+1,tv+n+1);
60     int len1=unique(th+1,th+n+1)-th-1;
61     int len2=unique(tv+1,tv+n+1)-tv-1;
62     for(int i=1;i<=n;i++)
63         h(i)=lower_bound(th+1,th+len1+1,h(i))-th,
64         v(i)=lower_bound(tv+1,tv+len2+1,v(i))-tv;
65     sort(a+1,a+n+1,cmp1);
66     for(int i=1;i<=n;i++)ans(i)=1;
67     CDQ(1,n);
68     sort(a+1,a+n+1,cmp1);
69 //    for(int i=1;i<=n;i++)cout<<"ans "<<i<<" "<<ans(i)<<endl;
70     for(int i=1;i<=n;i++)ans=max(ans,ans(i));
71     printf("%d\n",ans);
72     for(int i=1;i<=n;i++) cout<<(double)1/3<<" ";puts("");
73 }

第一问

先说第一问吧,本来觉得挺简单的,做起来才发现一直调不出来……第一问其实是一个比较容易看出来的三位偏序问题,只不过并不是简单的求和,而是用一个点前面h和v都大于他的点答案的最大值+1去更新这个点,所以树状数组要维护后缀,记得要把每个点的初始答案附成1。

第二问就比较麻烦了,一个点出现的概率等于$\frac{包含这个点的方案数}{总方案数}$,维护4个数组,f[i]表示以i为结尾的最大长度,g[i]表示以i为结尾最大长度的方案数,h[i]表示以i开头的最大长度,s[i]表示以i开头最大长度的方案数。两个要跑两边CDQ,这里之说第一遍,用树状数组维护后缀最大值及其方案数(用结构体或pair实现),CDQ时先递归处理左区间,然后考虑当前区间,最后递归处理右区间。至于答案的更新:

        if(tem.maxn==f(i))g(i)+=tem.num;else if(tem.maxn>f(i))f(i)=tem.maxn,g(i)=tem.num;

还有几点要注意:如果一个点不能包含在最长子序列中,那么选中他的概率为0。记得开double,这道题会爆longlong。

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<cmath>
  6 #define MAXN 50010
  7 #define LL long long
  8 #define int LL
  9 using namespace std;
 10 struct ddd
 11 {
 12     int t,h,v,ans;
 13     double f,g,he,s;
 14     #define t(x) a[x].t
 15     #define h(x) a[x].h
 16     #define v(x) a[x].v
 17     #define ans(x) a[x].ans
 18     #define f(x) a[x].f
 19     #define g(x) a[x].g
 20     #define he(x) a[x].he
 21     #define s(x) a[x].s
 22 }a[MAXN];
 23 int n,th[MAXN],tv[MAXN];
 24 bool cmp1(ddd a,ddd b){return a.t==b.t?(a.h==b.h?(a.v<b.v):a.h<b.h):a.t<b.t;}
 25 bool cmp2(ddd a,ddd b){return a.h==b.h?(a.t==b.t?(a.v>b.v):a.t<b.t):a.h>b.h;}
 26 bool cmp3(ddd a,ddd b){return a.t==b.t?(a.h==b.h?(a.v<b.v):a.h<b.h):a.t>b.t;}
 27 bool cmp4(ddd a,ddd b){return a.h==b.h?(a.t==b.t?(a.v<b.v):a.t<b.t):a.h<b.h;}
 28 double ans=1;
 29 #define lowbit(x) ((x)&(-(x)))
 30 struct cc{double maxn;double num;}C[MAXN];
 31 void add(int x,double y,double nu)
 32 {
 33     while(x)
 34     {
 35         if(C[x].maxn==y)C[x].num+=nu;
 36         else if(C[x].maxn<y)C[x].maxn=y,C[x].num=nu;
 37         x-=lowbit(x);
 38     }
 39 }
 40 void admin(int x)
 41 {while(x){C[x].maxn=C[x].num=0;x-=lowbit(x);}}
 42 cc ask(int x)
 43 {
 44     cc ans={0,0};
 45     while(x<=n)
 46     {
 47         if(C[x].maxn==ans.maxn)ans.num+=C[x].num;
 48         else if(C[x].maxn>ans.maxn)ans.maxn=C[x].maxn,ans.num=C[x].num;
 49         x+=lowbit(x);
 50     }
 51     return ans;
 52 }
 53 cc C2[MAXN];
 54 void add2(int x,double y,double nu)
 55 {
 56     while(x<=n)
 57     {
 58         if(C2[x].maxn==y)C2[x].num+=nu;
 59         else if(C2[x].maxn<y)C2[x].maxn=y,C2[x].num=nu;
 60         x+=lowbit(x);
 61     }
 62 }
 63 void admin2(int x)
 64 {while(x<=n){C2[x].maxn=C2[x].num=0;x+=lowbit(x);}}
 65 cc ask2(int x)
 66 {
 67     cc ans={0,0};
 68     while(x)
 69     {
 70         if(C2[x].maxn==ans.maxn)ans.num+=C2[x].num;
 71         else if(C2[x].maxn>ans.maxn)ans.maxn=C2[x].maxn,ans.num=C2[x].num;
 72         x-=lowbit(x);
 73     }
 74     return ans;
 75 }
 76 void CDQ(int l,int r)
 77 {
 78     if(l==r){return;}
 79     int mid=(l+r)>>1;
 80     CDQ(l,mid);
 81     sort(a+l,a+mid+1,cmp2);
 82     sort(a+mid+1,a+r+1,cmp2);
 83     int j=l;
 84     for(int i=mid+1;i<=r;i++)
 85     {
 86         while(j<=mid&&h(j)>=h(i))
 87         {
 88             add(v(j),f(j),g(j));j++;
 89         }
 90         cc tem=ask(v(i));tem.maxn++;
 91         if(tem.maxn==f(i))g(i)+=tem.num;
 92         else if(tem.maxn>f(i))f(i)=tem.maxn,g(i)=tem.num;
 93     }
 94     for(int i=l;i<j;i++)admin(v(i));
 95     sort(a+mid+1,a+r+1,cmp1);
 96     CDQ(mid+1,r);
 97 }
 98 void CDQ2(int l,int r)
 99 {
100     if(l==r){return;}
101     int mid=(l+r)>>1;
102     CDQ2(l,mid);
103     sort(a+l,a+mid+1,cmp4);
104     sort(a+mid+1,a+r+1,cmp4);
105     int j=l;
106     for(int i=mid+1;i<=r;i++)
107     {
108         while(j<=mid&&h(j)<=h(i))
109         {
110             add2(v(j),he(j),s(j));j++;
111         }
112         cc tem=ask2(v(i));tem.maxn++;
113         if(tem.maxn==he(i))s(i)+=tem.num;
114         else if(tem.maxn>he(i))he(i)=tem.maxn,s(i)=tem.num;
115     }
116     for(int i=l;i<j;i++)admin2(v(i));
117     sort(a+mid+1,a+r+1,cmp3);
118     CDQ2(mid+1,r);
119 }
120 signed main()
121 {
122 //    freopen("1.in","r",stdin);
123 //    freopen("out.out","w",stdout);
124
125     cin>>n;
126     for(int i=1;i<=n;i++)
127         cin>>h(i)>>v(i),t(i)=i,th[i]=h(i),tv[i]=v(i);
128     sort(th+1,th+n+1);
129     sort(tv+1,tv+n+1);
130     int len1=unique(th+1,th+n+1)-th-1;
131     int len2=unique(tv+1,tv+n+1)-tv-1;
132     for(int i=1;i<=n;i++)
133         h(i)=lower_bound(th+1,th+len1+1,h(i))-th,
134         v(i)=lower_bound(tv+1,tv+len2+1,v(i))-tv;
135     for(int i=1;i<=n;i++)f(i)=g(i)=he(i)=s(i)=1;
136     sort(a+1,a+n+1,cmp1);
137     CDQ(1,n);
138      for(int i=1;i<=n;i++)ans=max(ans,f(i));
139     printf("%0.0lf\n",ans);
140     sort(a+1,a+n+1,cmp3);
141     CDQ2(1,n);
142     double summ=0;
143     sort(a+1,a+n+1,cmp1);
144     for(int i=1;i<=n;i++)
145         if(fabs(f(i)-ans)<=1e-8) summ+=g(i);
146     for(int i=1;i<=n;i++)
147     {
148         if(f(i)+he(i)-1==ans){double ttt=(double)(1.0*g(i)*s(i))/summ;printf("%0.5lf ",ttt);}
149         else printf("0.00000 ");
150     }puts("");
151 }

View Code

转载于:https://www.cnblogs.com/Al-Ca/p/11291339.html

BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化)相关推荐

  1. BZOJ2244 [SDOI2011]拦截导弹 【cdq分治 + 树状数组】

    题目 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其 ...

  2. bzoj 2648 SJY摆棋子 cdq分治+树状数组

    题面 题目传送门 解法 同bzoj2716 自己cdq写的还是丑啊,别人A掉了我T飞了 代码 #include <bits/stdc++.h> #define inf 1 << ...

  3. P4093-[HEOI2016/TJOI2016]序列【CDQ分治,树状数组】

    正题 题目链接:https://www.luogu.com.cn/problem/P4093 题目大意 nnn个数字,每次有一个数字可能和原序列不同,但最多只有一个不同. 求所有情况下都满足的最长不降 ...

  4. [cdq分治][树状数组] Bzoj P3262 陌上花开

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...

  5. BZOJ 2244: [SDOI2011]拦截导弹 DP+CDQ分治

    2244: [SDOI2011]拦截导弹 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截 ...

  6. BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )

    考虑cdq分治, 对于[l, r)递归[l, m), [m, r); 然后计算[l, m)的操作对[m, r)中询问的影响就可以了. 具体就是差分答案+排序+离散化然后树状数组维护.操作数为M的话时间 ...

  7. hdu_5324_Boring Class(cdq分治+树状数组)

    题目链接:hdu_5324_Boring Class 题意: 给出n个二维点对,求LIS长度和编号字典序最小的LIS(x非增,y非减) 题解: dp[i]=max(dp[j]) (i>j,l[i ...

  8. CDQ分治 + 树状数组 ---- C. Goodbye Souvenir(三维偏序+思维)

    题目链接 题目大意: 给定长度为nnn的数组, 定义数字XXX在[l,r][l,r][l,r]内的值为数字XXX在[l,r][l,r][l,r]内最后一次出现位置的下标减去第一次出现位置的下标 给定m ...

  9. Educational Codeforces Round 17 E. Radio stations cdq分治 + 树状数组

    传送门 文章目录 题意 思路: 题意 有nnn个电台,对于每个电台iii有三个参数xi,ri,fix_i,r_i,f_ixi​,ri​,fi​,分别指他们的坐标.作用半径.频率.如果两个电台频率差值在 ...

最新文章

  1. Ubuntu14.04安装NVIDIA驱动后之后无法进入图形界面
  2. 1.有意义的命名(代码的整洁之道)
  3. 前端学习(1186):双向数据绑定
  4. jdbc写入和读取过程
  5. 04.卷积神经网络 W1.卷积神经网络(作业:手动/TensorFlow 实现卷积神经网络)
  6. 高薪诚聘项目经理,架构师,高级工程师,工程师,网页设计师
  7. 为什么非零实对称矩阵一定是正定矩阵
  8. 深度学习视觉目标跟踪算法毕业论文【matlab】
  9. Raid5数据恢复原理_两块盘离线数据恢复方法
  10. foxmail群发邮件怎么发?
  11. idc机房安装服务器系统,IDC机房运维之(硬件篇)
  12. csu1164 Dominating
  13. Heartbeat超时值
  14. matlab滞环比较控制器,滞环比较跟踪控制技术
  15. 如何用Python画一只狗狗——turtle基础
  16. 应对项目严重滞后4大有效补救方法
  17. windows重要信息(键盘、鼠标、计时器)
  18. 用python画竹子_智慧职教moocPython程序设计基础期末考试查题公众号答案
  19. 学习vb知识的方法总结
  20. 芯片中上拉下拉电阻有何作用?

热门文章

  1. RHS333-5 Kerberized NFSv4
  2. 十个鲜为人知的Linux命令 - Part 5
  3. CDH5之Unexpected error.Unable to verify database connection
  4. 四、物理优化(2)索引视图
  5. nginx 服务器的学习(1)
  6. 【Python-ML】SKlearn库特征选择SBS算法
  7. Java经典面试题(N人循环报M个数出列)实现
  8. 可视化---寻找路径与算法
  9. WingIDE 5的安装与破解方法
  10. linux解压tar到目录,在Linux系统中将tar文件解压到不同的目录中的教程