CodeForces - 1198A MP3(尺取)
题目链接:点击查看
题目大意:给出n个数字,表示不同的数据,现在我们需要对数据进行压缩,压缩的规则是:
现在给出一个I,表示内存大小为,n个数字中,相同的数据可以占用同一片内存,不同的数据必须占用不同的内存
在以上前提下,我们需要确定一个范围[l,r],这个区间不是数组的下标,而是数字的范围,然后对n个数进行操作:
- 在这个范围内的数字不用改变
- 小于l的所有数字都改成l
- 大于r的所有数字都改成r
现在我们需要求出在满足上述所有条件的情况下,n-(r-l+1)的最小值
题目分析:这个题就在读题上废了好大的功夫,简单来说为了让n-(r-l+1)尽量小,那么就要让r-l+1尽量大,也就是让整个区间尽量长,因为[l,r]他不是数组的下标,但我们可以将其转换为数组的下标来处理,其实就是对原数组排个序就好了,然后[l,r]就可以当下标来用了,首先我们必须知道,若想让r-l+1尽可能的大,那么就必须让区间[l,r]之间不同数字的个数恰好等于K才行,这算一种贪心的策略吧,显而易见?在处理之前,我们先求出来K来表示上面内存大小公式的计算结果,若K大于等于n个数中不同数字的个数,那么直接输出0即可,根本不用压缩了,而且注意一下当I求出来的指数很大的时候,大概大于20的时候,我们就可以直接输出0了,因为2的20次方已经大于1e6了,比n都大了,肯定满足条件
在判断完上述情况之后,剩下的我们可以用尺取法跑一边整个数组,这个尺取需要仔细设计一下,因为他是普通求和尺取的一种小变形,我们先用一个数组维护一下前缀和,但这个前缀和维护的是0~i中不同数字的个数,然后跑尺取的时候让r一直递增,让l随着r根据K来移动就行了,总的时间复杂度是n+n,也就是O(n),常数是2,具体实现看代码吧
代码:
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=4e5+100;int a[N],b[N];int main()
{
// freopen("input.txt","r",stdin);
// ios::sync_with_stdio(false);int n,I;scanf("%d%d",&n,&I);for(int i=1;i<=n;i++)scanf("%d",a+i);I=I*8/n;int k=I>20?(1<<20):(1<<I);sort(a+1,a+1+n);a[0]=-1;//因为a[i]的取值范围会涉及到0,所以我们初始化一个一定与a[i]不相等的数 for(int i=1;i<=n;i++){if(a[i]==a[i-1])b[i]=b[i-1];elseb[i]=b[i-1]+1;}if(k>=b[n])//特判一下return 0*printf("0");int ans;int l=1,r=1;int mmin=inf;while(r<=n)//尺取{ans=b[r++]-b[l]+1;//先求出当前范围内有多少个不同的数if(ans>k)//如果这个值大于内存K的话,就让l逼近r{ans-=b[l++];while(ans>k)//持续逼近{ans+=b[l++];//注意要将之前的值加回来ans-=b[l];//然后再减去当前位置的值}}if(ans==k)//如果满足条件,更新答案mmin=min(mmin,n-(r-l));}printf("%d\n",mmin);return 0;
}
CodeForces - 1198A MP3(尺取)相关推荐
- Codeforces Round #736 (Div. 2) D. Integers Have Friends ST表gcd + 尺取
传送门 文章目录 题意: 思路: 题意: 给你一个序列aaa,求一个最长的子序列[l,r][l,r][l,r]满足aimodm=ai+1modm=...=armodma_i\bmod m=a_{i+1 ...
- 【尺取或dp】codeforces C. An impassioned circulation of affection
http://codeforces.com/contest/814/problem/C [题意] 给定一个长度为n的字符串s,一共有q个查询,每个查询给出一个数字m和一个字符ch,你的操作是可以改变字 ...
- Codeforces Round #321 (Div. 2) B. Kefa and Company (尺取)
排序以后枚举尾部.尺取,头部单调,维护一下就好. 排序O(nlogn),枚举O(n) #include<bits/stdc++.h> using namespace std; typede ...
- CodeForces - 1358D The Best Vacation(前缀和+尺取)
题目链接:点击查看 题目大意:给出 n 个数组成的数列,每个元素都可以展开为 1 , 2 , 3 .... a[ n ] ,现在将数列首尾相接,要求选取一段长度为 x 的连续数列,使得元素和最大 题目 ...
- CodeForces - 1333C Eugene and an array(尺取)
题目链接:点击查看 题目大意:给出一个长度为 n 的数组 a,抛出 good 数组的定义: good 数组为数组 a 的一个子数组 good 数组的任意子数组之和均不为 0 (注意区分子数组和子数列的 ...
- The Best Vacation CodeForces - 1358D(贪心+尺取)
You've been in love with Coronavirus-chan for a long time, but you didn't know where she lived until ...
- 【CodeForces - 514D】R2D2 and Droid Army(二分+滑动窗口ST表,或 尺取+单调队列或STLmultiset)
题干: An army of n droids is lined up in one row. Each droid is described by m integers a1, a2, ..., a ...
- 【CodeForces - 616D 】Longest k-Good Segment (twopointer,尺取)
题干: The array a with n integers is given. Let's call the sequence of one or more consecutive element ...
- 【CodeForces - 660C】Hard Process (尺取 或 二分+滑窗,前缀和预处理)
题干: You are given an array a with n elements. Each element of a is either 0 or 1. Let's denote the l ...
最新文章
- Kuebernetes之DaemonSet
- 三星超过台积电 成为全球市值最高半导体公司
- c语言笔记照片_C语言学习笔记
- 在地理文本处理技术上,高德有哪些技巧?
- haroopad夜间模式与数学公式显示
- hadoop join之map side join
- caffemodel权值可视化(转)
- springboot整合elasticjob
- 在Dockerfile中安装本地whl包
- 第 3 章 运行时数据区概述及线程
- OMAPL多核异构通信驱动AD9833波形发生器-Notify组件
- 升降压电路的设计和分析
- 阿拉伯数字 - 书法
- Edge浏览器被篡改主页
- LZJ的python的第8次打卡
- YouTube:如何删除油管频道Channel
- mt2503 在MMI版本实现AT+CPBF
- 如何正确安装朗文英文当代大词典(2CD版)
- SQL 对含有字母和数字的列排序
- iOS项目开发实战——iOS网络编程获取网页Html源代码