[Codeforces 1199C]MP3(离散化+二分答案)

题面

给出一个长度为n的序列\(a_i\)和常数I,定义一次操作[l,r]可以把序列中<l的数全部变成l,>r的数全部变成r。每次操作的代价为改变数的个数。问:要让操作后序列里不同数的个数\(k\)满足$n \lceil \log _2 k\rceil \leq 8I $,操作的最小代价

分析

首先把a离散化,这样[l,r]都在\(10^5\)的级别。枚举l,发现r显然有单调性。操作后不同数的个数随r的增大而减小(考虑极端情况l=r,操作后所有数相同。若\(r_1\)满足条件,那\(r_2<r_1\)也一定满足条件。而操作的最小代价随r增大而减小。所以我们只需要对于每个l找到最大的满足条件的r即可。

考虑判定:我们把a排序,记\(cnt(l,r)\)表示满足\(a_i \in [l,r]\)的\(i\)的个数,m为离散化后的最大值。那么操作的代价为\(cnt(1,l-1)+cnt(r+1,m)\),不同数的个数为\(r-l+1\)(操作完之后最小值变成l,最大值变成r,由于我们离散化过,[l,r]内的数一定是连续的,所有个数为[r-l+1])

那么我们只要预处理前缀和\(sum(v)\)表示整个序列值<=v的个数,离散化后可以\(O(n)\)预处理,\(cnt(l,r)=sum(r)-sum(l-1)\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define INF 0x3f3f3f3f
#define maxn 800000
using namespace std;
int n,m,I;
int a[maxn+5];
int b[maxn+5];
int sum1[maxn+5]; inline int cnt(int l,int r){
return sum1[r]-sum1[l-1];
}
int check(int lb,int rb){
int ans1=cnt(1,lb-1);
int ans2=cnt(rb+1,m);
int k=rb-lb+1;
// int cnt=2+sum1[lb+1]+sum1[rb-1];
if(ceil(log2(k))*n<=I*8) return ans1+ans2;
else return -1;
}
int bin_search(int t){ int l=t,r=m;
int ans=INF;
int mid;
while(l<=r){
mid=(l+r)>>1;
int val=check(t,mid);
if(val!=-1){
ans=val;
l=mid+1;
}else r=mid-1;
}
return ans;
} int mark[maxn+5];
int main(){
// freopen("input.txt","r",stdin);
scanf("%d",&n);
scanf("%d",&I);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(a+1,a+1+n);
sort(b+1,b+1+n);
m=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+m,a[i])-b;
for(int i=1;i<=n;i++){
sum1[a[i]]++;
}
for(int i=1;i<=m;i++) sum1[i]+=sum1[i-1];
// printf("%d\n",m);
int ans=INF;
for(int l=1;l<=m;l++){
int tmp=bin_search(l);
ans=min(ans,tmp);
}
printf("%d\n",ans);
}

[Codeforces 1199C]MP3(离散化+二分答案)的更多相关文章

  1. Codeforces 772A Voltage Keepsake - 二分答案

    You have n devices that you want to use simultaneously. The i-th device uses ai units of power per s ...

  2. 2018.12.08 codeforces 939E. Maximize!(二分答案)

    传送门 二分答案好题. 题意简述:要求支持动态在一个数列队尾加入一个新的数(保证数列单增),查询所有子数列的 最大值减平均值 的最大值. 然而网上一堆高人是用三分做的. 我们先考虑当前的答案有可能由什 ...

  3. Educational Codeforces Round 21 Problem F (Codeforces 808F) - 最小割 - 二分答案

    Digital collectible card games have become very popular recently. So Vova decided to try one of thes ...

  4. codeforces 633D - Fibonacci-ish 离散化 + 二分查询

    Fibonacci-ish Yash has recently learnt about the Fibonacci sequence and is very excited about it. He ...

  5. Codeforces - 1199C - MP3 - 尺取

    https://codeforc.es/contest/1199/problem/C 擦,最后移位运算符溢出了,真的蠢. 肯定是选中间的连续的某段是最优的,维护这个段的长度和其中的元素种类就可以了.小 ...

  6. Codeforces 700A As Fast As Possible(二分答案)

    [题目链接] http://codeforces.com/problemset/problem/700/A [题目大意] 有一辆限载k人速度为v2的车,n个步行速度均为v1的人要通过一段长度为l的距离 ...

  7. Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案 主席树 区间合并)

    链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ...

  8. Codeforces Round #425 (Div. 2) Problem C Strange Radiation (Codeforces 832C) - 二分答案 - 数论

    n people are standing on a coordinate axis in points with positive integer coordinates strictly less ...

  9. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划

    There are n people and k keys on a straight line. Every person wants to get to the office which is l ...

随机推荐

  1. :last-child----represents the last element among a group of sibling elements.

    CSS伪类 :last-child 代表在一群兄弟元素中的最后一个元素. 举个例子: 从代码和图可以看出:last-child选择了最后一个li标签. 同时,我们换另外一段代码,看看是否还有这样的效果 ...

  2. 【leetcode】1106. Parsing A Boolean Expression

    题目如下: Return the result of evaluating a given boolean expression, represented as a string. An expres ...

  3. 【leetcode】491. Increasing Subsequences

    题目如下: 解题思路:这题把我折腾了很久,一直没找到很合适的方法,主要是因为有重复的数字导致结果会有重复.最后尝试用字典记录满足条件的序列,保证不重复,居然Accept了. 代码如下: class S ...

  4. delphi datetimetounix 和 unixtodatetime 全平台(FIREMONKEY)时区修正

    可能平时在转换UNIX时间时没有注意结果,当转换成UNIX时间后,再转换回来对比发现时间和标准时间差了8个小时.网上有相关的修正方法,但仅适用于WINDOWS平台,以下方法全平台适合. datetim ...

  5. 整合spring cloud云架构 - 根据token获取用户信息

    根据用户token获取yoghurt信息的流程: /** * 根据token获取用户信息 * @param accessToken * @return * @throws Exception */ @ ...

  6. (3.3)狄泰软件学院C++课程学习剖析四

    对课程前面40课的详细回顾分析(二) 1.一个类的成员变量是对于每个对象专有的,但是成员函数是共享的. 2.构造函数只是决定一个对象的初始化状态,而不能决定对象的诞生.二阶构造人为的将初始化过程分为了 ...

  7. plt.imshow()为什么不能显示同时显两张照片

    在编程的过程中发现plt.imshow()不能同时显示两张照片,如果有两条plt.imshow()语句处于一前一后的位置,那么程序运行后只会显示后面的图片.如果想让每一张图片都显示出来,需要在每一个p ...

  8. Java测试笔记(ATM)

    本次Java测试主要是做一个与ATM相似的系统,用文本文件来作为用户数据库,实现存款.取款.转账.修改密码.查询余额的功能.在做这次测试之前老师并没有讲解与Java相关的知识,所以这就需要我们自学Ja ...

  9. 转:SqlBulkCopy类进行大数据(一万条以上)插入测试

    转自:https://www.cnblogs.com/LenLi/p/3903641.html 结合博主实例,自己测试了一下,把数据改为3万行更明显!! 关于上一篇博客中提到的,在进行批量数据插入数据 ...

  10. Tarjan算法整理

    众所周知,tarjan是个非常nb的人,他发明了很多nb的算法,tarjan算法就是其中一个,它常用于求解强连通分量,割点和桥等.虽然具体实现的细节不太一样,但是大体思路是差不多的.先来说一下大体思路 ...