0811 钟 区间第K大(kth)

时间:2022-12-16 22:40:20

0811 钟 区间第K大(kth)

大模拟,这真是没什么好说的,一个一个时间往后走就可以了

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000005
using namespace std;
int col,n,sz;
int f[105][105],a[maxn],c[maxn];
int pre[maxn],nex[maxn],sum[105];
bool vis[105];
inline int read()
{
int x=0,op=1;;
char ch=getchar();
if(ch=='-') op=-1;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*op;
}
inline void del(int x)
{
nex[pre[x]]=nex[x];
pre[nex[x]]=pre[x];
}
int main()
{
col=read();n=read();
sz=col;
for(int i=1;i<=col;i++)
for(int j=1;j<=col;j++) scanf("%d",&f[i][j]);
for(int i=1;i<=n;i++){ a[i]=read(); c[i]=1; sum[a[i]]++; }
for(int i=0;i<=n+1;i++){ pre[i]=i-1;nex[i]=i+1;}
int op=0;
while(1)
{
int y,x;
for(x=nex[0];x<=n;x=y){
y=nex[x];
if(y>n) break;
c[x]+=f[a[x]][a[y]];
c[y]+=f[a[y]][a[x]];
}
for(x=nex[0];x<=n;x=nex[x])
if(c[x]<=0){
del(x);
sum[a[x]]--;
if(sum[a[x]]==0) sz--;
}
if(sz==1) break;
}
printf("%d\n",a[nex[0]]);
//while(1);
return 0;
}
区间第k大

每次询问有多少个区间第k大的数为x

从每一个数往两边找,对每一个数记录sum[i] ,到第i位比x大的数的个数,num[i] 有i个比x大的数的区间的个数

对于x,左边选i个比他大的数,右边选j个,那么x在区间的排名就是i+j+1,统计每个数对答案的贡献,对于相等的数,为了防止某些区间重复计算,可以规定下标大的数比较大

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 2005
using namespace std;
int n,Q;
int f[maxn][maxn],a[maxn];
int num1[maxn],num2[maxn],sum[maxn];
inline int read()
{
int x=0,op=1;
char ch=getchar();
if(ch=='-') op=-1;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*op;
}
void pre()
{
int op;
for(int i=1;i<=n;i++){
op=a[i];
memset(num1,0,sizeof(num1));
memset(num2,0,sizeof(num2));
memset(sum,0,sizeof(sum));
sum[i]=0;num1[0]++;num2[0]++;
for(int j=i-1;j>=1;j--){
if(a[j]>a[i]) sum[j]=sum[j+1]+1;
else sum[j]=sum[j+1];
num1[sum[j]]++;
}
for(int j=i+1;j<=n;j++){
if(a[j]>=a[i]) sum[j]=sum[j-1]+1;
else sum[j]=sum[j-1];
num2[sum[j]]++;
}
for(int i=0;i<=sum[1];i++)
for(int j=0;j<=sum[n];j++){
f[op][i+j+1]+=num1[i]*num2[j];
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
n=read();Q=read();
for(int i=1;i<=n;i++) a[i]=read();
pre();
int k,x;
while(Q--){
k=read();x=read();
printf("%d\n",f[x][k]);
}
//while(1);
return 0;
}