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; }