牛客小白月賽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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章