【LGR-150-Div.2】洛谷 8 月月赛 I & RiOI Round 2 B题 题解
include13_fAKe · · 题解
前言
这是我第一次自己完成洛谷月赛的 Div.2B。
但因为这天下午我在和小伙伴下棋,没能按时参与月赛。
题意
给定一个
有
询问之间相互独立。换言之,每次询问前可以重新排列。
思路
Subtask 1:
枚举重排的所有情况,时间复杂度
Subtask 2:
首先发现一个性质:既然矩阵可以重排,则最好要把大的数放在不同的列中。
然后,我们可以发现:一个数无论在哪一行,都可以被放在任何一列。
我们可以将
然后,顺序枚举
但是,
时间复杂度
其实,即使不排序也能过。时间复杂度
Subtask 3:
实现得较好、常数较小的
但我们排了序的,又可以怎样优化呢?二分!
此外,我们可以先判断
然后我们在前
时间复杂度
代码
我就是从小到大排序的,这样做很麻烦(前面已经说过了)。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n;
int q;
int cnt;
int a[N];
void solve(int v){
int l=n*(n-1)+1;
int r=n*n;
if(v<=a[l]){
printf("%d\n",n);
return;
}
if(v>a[r]){
printf("0\n");
return;
}
int mid=l+r>>1;
while(l<r){
if(v<=a[mid]) r=mid;
else l=mid+1;
mid=l+r>>1;
}
printf("%d\n",n*n+1-l);
return;
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int num;
scanf("%d",&num);
a[++cnt]=num;
}
}
sort(a+1,a+cnt+1);
while(q--){
int v;
scanf("%d",&v);
solve(v);
}
}