中文题意不解释
一开始以为是个线段树之类的数据结构 毕竟还有查询
但是算了一下时间复杂度发现直接暴力就可以
O(n*sqrt(n)*sqrt(n)*log(sqrt(n))) 大概只有2e6的复杂度
对于每一个n对每个k≤sqrt(n)预处理排序 大于的部分直接计算就可以
反正还是很水的了
记得M是构造两棵线段树 但是没来得及做 晚上有时间的话补上
1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(a) cerr<<#a<<"=="<<a<<endl 4 using namespace std; 5 typedef long long ll; 6 typedef pair<int,int> pii; 7 8 const int maxn=2e4+10; 9 10 int n,m; 11 int a[maxn]; 12 vector<int>ans[205]; //也不知道会不会爆内存 就直接用vector了 13 14 bool cmp(int a,int b) 15 { 16 return a>b; 17 } 18 19 void init() 20 { 21 for(int i=1;i<=sqrt(n);i++) //预处理sqrt(n)的部分 22 { 23 ans[i].clear(); 24 for(int j=0;j<n;j+=i) 25 { 26 ans[i].push_back(a[j]); 27 } 28 sort(ans[i].begin(),ans[i].end(),cmp); 29 } 30 } 31 32 int solve(int k,int s) 33 { 34 if(k <= sqrt(n)) //对于≤sqrt(n)的k值直接查询 35 { 36 if(s>ans[k].size()) return -1; 37 else return ans[k][s-1]; 38 } 39 else //大于的直接暴力 反正也没几个数 40 { 41 vector<int>tmp; 42 tmp.clear(); 43 for(int i=0;i<n;i+=k) 44 { 45 tmp.push_back(a[i]); 46 } 47 sort(tmp.begin(),tmp.end(),cmp); 48 if(s>tmp.size()) return -1; 49 else return tmp[s-1]; 50 } 51 } 52 53 int main() 54 { 55 int T; 56 scanf("%d",&T); 57 while(T--) 58 { 59 cl(a,0); 60 scanf("%d%d",&n,&m); 61 for(int i=0;i<n;i++) 62 { 63 scanf("%d",&a[i]); 64 } 65 init(); //预处理 66 while(m--) 67 { 68 int k,s; 69 scanf("%d%d",&k,&s); 70 printf("%d ",solve(k,s)); 71 } 72 } 73 return 0; 74 }/* 75 76 1 77 5 2 78 2 5 3 4 1 79 2 4 80 2 1 81 82 */