Codeforces Round #576 (Div. 2) C. MP3

C. MP3 原题地址

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

One common way of digitalizing sound is to record sound intensity at particular time moments. For each time moment intensity is recorded as a non-negative integer. Thus we can represent a sound file as an array of nn non-negative integers.

If there are exactly KK distinct values in the array, then we need k=log2Kk=⌈log2⁡K⌉ bits to store each value. It then takes nknk bits to store the whole file.

To reduce the memory consumption we need to apply some compression. One common way is to reduce the number of possible intensity values. We choose two integers lrl≤r, and after that all intensity values are changed in the following way: if the intensity value is within the range [l;r][l;r], we don't change it. If it is less than ll, we change it to ll; if it is greater than rr, we change it to rr. You can see that we lose some low and some high intensities.

Your task is to apply this compression in such a way that the file fits onto a disk of size II bytes, and the number of changed elements in the array is minimal possible.

We remind you that 11 byte contains 88 bits.

k=log2Kk=⌈log2K⌉ is the smallest integer such that K2kK≤2k. In particular, if K=1K=1, then k=0k=0.

Input

The first line contains two integers nn and II (1n41051≤n≤4⋅105, 1I1081≤I≤108) — the length of the array and the size of the disk in bytes, respectively.

The next line contains nn integers aiai (0ai1090≤ai≤109) — the array denoting the sound file.

Output

Print a single integer — the minimal possible number of changed elements.

Examples
input
Copy
6 1
2 1 2 3 4 3
output
Copy
2
input
Copy
6 2
2 1 2 3 4 3
output
Copy
0
input
Copy
6 1
1 1 2 2 3 3
output
Copy
2
Note

In the first example we can choose l=2,r=3l=2,r=3. The array becomes 2 2 2 3 3 3, the number of distinct elements is K=2K=2, and the sound file fits onto the disk. Only two values are changed.

In the second example the disk is larger, so the initial file fits it and no changes are required.

In the third example we have to change both 1s or both 3s.

 

题意:给你 I bytes 大小的空间让你存一个音乐,存法就是记录这个音乐中有K个不同强度(即不同大小)的数,占用空间为n*logK/log2

你可以进行一些操作,把区间[l,r]之外的数字小于l改成l,大于r改成r,实际就是删除掉,因为只有不同的数字对于空间才有贡献

那么问你最少删除多少个数字可以把这歌存在I bytes的内存中?

思路:将给定的数组排序,然后离散化在一个连续的数组中,数组大小即K,数组中每一位存这个强度下的个数,然后用2的8I/n向下取整次方求出最长的强度区间长度len,如果长度大于等于K,一定能存下,如果小于那个遍历所有长度为len的区间个数sum0,找到最小的sumall-sum0

 

 

#include<iostream>
#include<algorithm>
using namespace std;
const int M=4e5+10;
int n,I;
int a[M],b[M];
int quicpow(int x,int y) {//快速幂 
    int ans=1;
    int base=x;
    while (y) {
        if (y&1)ans=ans*base;
        base=base*base;
        y>>=1;
    }
    return ans;
}
int main(){
    cin>>n>>I;
    int len=8*I/n;//先让len等于它的指数 
    for(int i=0;i<n;i++)cin>>a[i];
    int k=1;
    sort(a,a+n);
    for(int i=0;i<n;k++){//离散化 
        int j=i+1;
        while(a[i]==a[j]&&j<n){
            j++;
        }
        b[k]=j-i;
        i=j;
    }
    k--;
    b[0]=0;
    for(int i=1;i<=k;i++)b[i]+=b[i-1];//前缀和 
    if(len>=22)cout<<0;//计算log 4e5/log2 不会超过22,如果指数大于22一定可以存下 
    else {
        len=quicpow(2,len);//让len等于长度 
        if(len>=k)cout<<0;
        else {
            int sumall=b[k]-b[0];
            int mi=sumall;
            for(int i=len;i<=k;i++){
                mi=min(mi,sumall-b[i]+b[i-len]);
            }
            cout<<mi;
        }
    }
    return 0;
}

 

 

 

 

 

 

posted @ 2019-07-31 11:09  GeraldG  阅读(184)  评论(0编辑  收藏  举报