当前位置: 首页 > news >正文

BZOJ 2244: [SDOI2011]拦截导弹 [CDQ分治 树状数组]

传送门

题意:三维最长不上升子序列以及每个元素出现在最长不上升子序列的概率


 

$1A$了好开心

首先需要从左右各求一遍,长度就是$F[0][i]+F[1][i]-1$,次数就是$G[0][i]*G[1][i]$

我们可以用一些转换来简化代码

反转之后变成$LIS$,然后再反转并且$x,y$取反还是$LIS$,写一遍就可以啦

然后本题的树状数组需要维护最大值以及最大值的数量,还有一个时间戳

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=5e4+5,INF=1e9;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m;
int mp[N];
void iniMP(){
    sort(mp+1,mp+1+m);
    int p=0;
    mp[++p]=mp[1];
    for(int i=2;i<=m;i++) if(mp[i]!=mp[i-1]) mp[++p]=mp[i];
    m=p;
}
int Bin(int v){
    int l=1,r=m;
    while(l<=r){
        int mid=(l+r)>>1;
        if(v==mp[mid]) return mid;
        else if(v<mp[mid]) r=mid-1;
        else l=mid+1;
    }
    return 0;
}
int c[N],mark[N],CL;double cnt[N];
inline int lowbit(int x){return x&-x;}
inline void upd(int p,int f,double g){
    for(;p<=m;p+=lowbit(p)){
        if(mark[p]!=CL) mark[p]=CL,c[p]=f,cnt[p]=g;
        else if(c[p]<f) c[p]=f,cnt[p]=g;
        else if(c[p]==f) cnt[p]+=g;
    }
}
inline void que(int p,int &f,double &g){
    for(;p;p-=lowbit(p)) if(mark[p]==CL){
        if(c[p]>f)  f=c[p],g=cnt[p];
        else if(c[p]==f) g+=cnt[p];
    }
}
struct Data{
    int x,y,id;
}a[N];
int ref[N];
inline bool cmpX(int p,int q){
    return a[p].x==a[q].x ? a[p].id<a[q].id : a[p].x<a[q].x;
}
int F[2][N];double G[2][N];
void CDQ(int l,int r,int tp){
    if(l==r) return;
    int mid=(l+r)>>1;
    CDQ(l,mid,tp);
    for(int i=l;i<=r;i++) ref[i]=i;
    sort(ref+l,ref+r+1,cmpX);
    int *f=F[tp]; double *g=G[tp];
    CL++;
    for(int i=l;i<=r;i++){
        int _=i;i=ref[i];
        if(a[i].id<=mid) upd(a[i].y,f[a[i].id],g[a[i].id]);
        else{
            int v=0;double sum=0;que(a[i].y,v,sum);
            v++;
            if(v>f[a[i].id]) f[a[i].id]=v,g[a[i].id]=sum;
            else if(v==f[a[i].id]) g[a[i].id]+=sum;
        }
        i=_;
    }
    CDQ(mid+1,r,tp);
}
int main(){
    freopen("in","r",stdin);
    n=read();
    for(int i=1;i<=n;i++) a[i].x=read(),mp[++m]=a[i].y=read();
    iniMP();
    for(int i=1;i<=n;i++) a[i].y=Bin(a[i].y);
    for(int i=1;i<=n;i++) F[0][i]=F[1][i]=G[0][i]=G[1][i]=1;
    reverse(a+1,a+1+n);
    for(int i=1;i<=n;i++) a[i].id=i;
    CDQ(1,n,0);
    //for(int i=1;i<=n;i++) printf("F0  %d %d %d  %d %lf\n",i,a[i].x,a[i].y,F[0][i],G[0][i]);
//puts("---");
    reverse(a+1,a+1+n);
    for(int i=1;i<=n;i++) a[i].y=m-a[i].y+1,a[i].x=INF-a[i].x,a[i].id=i;
    CDQ(1,n,1);
    //for(int i=1;i<=n;i++) printf("F1  %d %d %d  %d %lf\n",i,a[i].x,a[i].y,F[1][i],G[1][i]);

    for(int i=1;i<=n/2;i++) swap(F[0][i],F[0][n-i+1]),swap(G[0][i],G[0][n-i+1]);
    int ans=0;double tot=0;
    for(int i=1;i<=n;i++) ans=max(ans,F[0][i]);
    for(int i=1;i<=n;i++) if(F[0][i]==ans) tot+=G[0][i];//printf("tot %lf\n",tot);
    printf("%d\n",ans);
    for(int i=1;i<=n;i++){
        if(F[0][i]+F[1][i]-1!=ans) printf("%.5lf ",0.0);
        else printf("%.5lf ",G[0][i]*G[1][i]/tot);
    }
}

相关文章:

  • Jquery里live事件移除原因
  • Java NIO中的通道Channel(一)通道基础
  • java栈与队列面试题
  • java中正则表达式的使用
  • 拦截器与过滤器的区别
  • RPM方式安装MySQL5.6
  • PHP 小技巧
  • Linux系统中三类重要文件的作用与区别
  • 《剑指offer》-前n项和不准用通解和各种判断
  • 内存映射文件原理探索(转载)
  • X-Frame-Options 响应头
  • Excel 总结
  • sklearn中随机森林的参数
  • CHIL-ORACLE-修改密码
  • itunes 无法构建版本问题
  • Create React App 使用
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • Git同步原始仓库到Fork仓库中
  • go语言学习初探(一)
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • Redis 懒删除(lazy free)简史
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • vuex 笔记整理
  • 简单易用的leetcode开发测试工具(npm)
  • 面试总结JavaScript篇
  • 前端技术周刊 2019-02-11 Serverless
  • 前端临床手札——文件上传
  • 入门到放弃node系列之Hello Word篇
  • 思考 CSS 架构
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 阿里云服务器如何修改远程端口?
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #{} 和 ${}区别
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • $(selector).each()和$.each()的区别
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (待修改)PyG安装步骤
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (黑马C++)L06 重载与继承
  • (论文阅读30/100)Convolutional Pose Machines
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (算法设计与分析)第一章算法概述-习题
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (原)本想说脏话,奈何已放下
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)C#调用WebService 基础
  • (转)shell调试方法
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .naturalWidth 和naturalHeight属性,
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析