Codeforces Round 963 (Div. 2)

C. Light Switches

所有灯周期均为2k,需要找到一个mod(2k)的数res,让所有到这个时刻都是亮的
投影到[0,2
k-1]的数组,有的跨过头尾,要破环成链,[0,4k-1]。找到res,因为周期2k,所以这样的res2k内只有一个,加到4k上跨过的只加一遍,就可以保证4k内只有一个,枚举[0,4k-1]就可以找到res
最后返回2*k

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
const ll N=200010;
ll n,k;
ll a[N];
ll b[4*N];
ll bb[4*N];

bool cmp(ll x,ll y){
    return x<=y;
//return x-x%(2*k)<=y-y%(2*k);
}

int main(){
ll T;cin>>T;
while(T--){
    cin>>n>>k;
     for(ll i=0;i<=4*k-1;i++)b[i]=0;
    for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            ll t=a[i];
            b[t%(2*k)]++;b[t%(2*k)+k]--;
            if(t%(2*k)+k+2*k<=4*k-1){b[t%(2*k)+2*k]++;b[t%(2*k)+k+2*k]--;}
    }
    sort(a+1,a+n+1);

    for(ll i=0;i<=4*k-1;i++){
        if(i==0){
            bb[i]=b[i];
        }else bb[i]=bb[i-1]+b[i];
    }
    ll res=-1;
    for(ll i=0;i<=4*k-1;i++){
           // cout<<bb[i]<<" ";
        if(bb[i]>=n){
            res=i;break;
        }
    }//cout<<endl;
    if(res==-1)printf("-1\n");
    else {
            res%=(2*k);
        if(a[n]-a[n]%(2*k)+res>=a[n])
        printf("%lld\n",a[n]-a[n]%(2*k)+res);
        else printf("%lld\n",a[n]-a[n]%(2*k)+res+2*k);
    }

}


}

D. Med-imize

中位数常见二分,能否凑出>=n-(n+1)/2+1个>=mid的数

(i-1)%k0必是第一个,第一个必是(i-1)%k0
留着:
前面全删掉是b[i]
不留:
不作为第一个,为了更新后面其他modk同余的i f[i-k]

其他的(i-1)%k!=0
留着:
接到前面b[i]
不留:
为了更新后面其他modk同余的i f[i-k]

不是很能理解

#include<iostream>
using namespace std;
#include<algorithm>
#define ll long long
const ll N=500010;ll n,k;
ll f[N];
ll a[N];
ll b[N];

bool check(ll x){
    for(ll i=1;i<=n;i++){
            if(a[i]>=x)b[i]=1;else b[i]=-1;
    }
    for(ll i=1;i<=n;i++)f[i]=-1e17;
 f[0]=0;
 for(ll i=1;i<=n;i++){
    if((i-1)%k==0){
            f[i]=b[i];
        if(i-k>=0)f[i]=max(f[i],f[i-k]);
    }else {
        if(i-k>=0)f[i]=max(f[i],f[i-k]);
        if(i-1>=0)f[i]=max(f[i],f[i-1]+b[i]);
    }
 }

    return f[n]>0;
}

int main(){
ll T;cin>>T;
while(T--){
cin>>n>>k;
for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
if(n<=k){
    sort(a+1,a+n+1);
    printf("%lld\n",a[(n+1)/2]);continue;
}

ll l=1;ll r=1e9;
while(l<r){
ll mid=(l+r+1)>>1;
//cout<<"check"<<mid<<endl;
if(check(mid))l=mid;
else r=mid-1;
}
printf("%lld\n",l);
}


}
posted @ 2025-07-09 13:09  arin876  阅读(3)  评论(0)    收藏  举报