Codeforces Round 963 (Div. 2)
C. Light Switches
所有灯周期均为2k,需要找到一个mod(2k)的数res,让所有到这个时刻都是亮的
投影到[0,2k-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);
}
}

浙公网安备 33010602011771号