【UR #4】元旦激光炮
【UR #4】元旦激光炮
下文中令序列为 \(1\)-index 的。
考虑对 \(i > n_a\),令 \(a_i = 2147483647\),\(b\) 与 \(c\) 同理。
对于 \(k\),我们考虑定义 \(l = \lfloor \dfrac{k}{3} \rfloor\),并询问 \(a_l,b_l,c_l\)。
设 \(a_l = \min(a_l,b_l,c_l)\),同时钦定在 \(=a_l\) 的数中 \(a_l\) 的排名最小。
显然,排名比 \(a_l\) 小的数个数最多为 \(3(l-1)\),则 \(a_l\) 的排名最多为 \(3l-2\)。
显然,\(3l-2 < k\),所以我们可以删除 \(a_1\) 到 \(a_l\)。
这样的做法在 \(k \leq 2\) 时只能暴力,我们取出每个序列前 \(k\) 个数比较即可。
#include<iostream>
using namespace std;
int main(){
int ans=0;
for(int i=1;i<=300000;i++){
int sum=0,tmp=i;
while(tmp>2){
sum+=3;
tmp-=tmp/3;
}
sum+=3*tmp;
ans=max(ans,sum);
}
cout<<ans;
return 0;
}
运行上述代码,得到的结果为 \(96\),故可以通过。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include "kth.h"
using namespace std;
const int A=1,B=2,C=3,INF=2147483647;
int na,nb,nc,num_list[10];
int query(int pos,int flag){
if(flag==A){
if(pos>na){
return INF;
}
else{
return get_a(pos-1);
}
}
if(flag==B){
if(pos>nb){
return INF;
}
else{
return get_b(pos-1);
}
}
if(flag==C){
if(pos>nc){
return INF;
}
else{
return get_c(pos-1);
}
}
}
int query_kth(int n_a,int n_b,int n_c,int k){
na=n_a;
nb=n_b;
nc=n_c;
int pre_a=0,pre_b=0,pre_c=0;
while(k>2){
int l=k/3;
int num_a=query(pre_a+l,A),num_b=query(pre_b+l,B),num_c=query(pre_c+l,C);
int minn=INF,flag;
if(num_a<=minn){
minn=num_a;
flag=A;
}
if(num_b<=minn){
minn=num_b;
flag=B;
}
if(num_c<=minn){
minn=num_c;
flag=C;
}
if(flag==A){
pre_a+=l;
}
if(flag==B){
pre_b+=l;
}
if(flag==C){
pre_c+=l;
}
k-=l;
}
if(k==1){
num_list[1]=query(pre_a+1,A);
num_list[2]=query(pre_b+1,B);
num_list[3]=query(pre_c+1,C);
sort(num_list+1,num_list+4);
return num_list[1];
}
if(k==2){
num_list[1]=query(pre_a+1,A);
num_list[2]=query(pre_b+1,B);
num_list[3]=query(pre_c+1,C);
num_list[4]=query(pre_a+2,A);
num_list[5]=query(pre_b+2,B);
num_list[6]=query(pre_c+2,C);
sort(num_list+1,num_list+7);
return num_list[2];
}
}

浙公网安备 33010602011771号