牛客小白月赛80C/D又放学辣

C

这么小的数据范围,想必胡搞就可以了。


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,k;
struct cll{
    int p;
    int id;
}cl[105];
int x;
int ans[205];
bool cmp(cll x,cll y){
    return x.p>y.p;
}
void deal(int x){
    if(cl[x].p+k>n){
        ans[cl[x].id]=-1;
        return ;
    }
    int sum=0;
    for(int i=1;i<=m+1;++i){
      //  if(i==x) continue;
        sum=0;
        for(int j=1;j<i;++j){
            if(j==x) continue;
            sum+=cl[j].p;
        }
        int ex=k-(sum-(i-1-(x<i))*cl[i].p);
        if(ex<0){
            ans[cl[x].id]=cl[i].p+(-ex)/(i-1-(x<i))+((-ex)%(i-1-(x<i))!=0);
            return ;
        }else{
            if(ex==0){
            ans[cl[x].id]=cl[i].p;
            return ;
            }
        }
    }
    return ;
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i){
        scanf("%d",&x);
        cl[x].p++;
    }
    for(int i=1;i<=m;++i){
        cl[i].id=i;
    }
    sort(cl+1,cl+m+1,cmp);
    for(int i=1;i<=m;++i){
        deal(i);
    }
    for(int i=1;i<=m;++i){
        cout<<ans[i]<<" ";
    }
    return 0;
}

D 数据很大,显然需要对于单个同学log时间内解决,怎么办呢?二分答案。二分答案怎么检查呢?再二分答案。
利用两个二分,就可以在\(o(nlogmlogm)\)时间内解决问题辣。


nclude<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,k;
int x;
int sum[1000006];
struct cl{
    int num;
    int id;
}a[1000006];
int ans[1000006];
bool cmp(cl x,cl y){
    return x.num<y.num;
}
int bs(int x){
    int l=1;
    int r=m;
    while(l<r){
        int mid=(l+r)>>1;
        if(a[mid].num>=x) r=mid;
        else l=mid+1;
    }
    return l;
}
bool che(int x,int kk){
    int p=bs(kk);
    if(p>m) return 1;
    else if(p<=x) return sum[p]-a[x].num-(m-p)*(kk-1)-1<k;
    else return sum[p]-(m-p+1)*(kk-1)-1<k;
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i){
        scanf("%d",&x);
        a[x].num++;
    }
    for(int i=1;i<=m;++i)
            a[i].id=i;
    sort(a+1,a+m+1,cmp);
    for(int i=m;i>=1;--i)
        sum[i]=sum[i+1]+a[i].num;
    for(int i=1;i<=m;++i){
        if(a[i].num+k>n){
            ans[a[i].id]=-1;
            continue;
        }
        int l=0;
        int r=n-a[i].num-k;
        while(l<r){
            int mid=(l+r+1)>>1;
            if(che(i,mid)) r=mid-1;
            else l=mid;
        }
        ans[a[i].id]=l;
    }
    for(int i=1;i<=m;++i)
        cout<<ans[i]<<" ";
    return 0;
}

posted @ 2023-11-05 20:29  Simex  阅读(5)  评论(0编辑  收藏  举报