Hints of sd0061
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1839 Accepted Submission(s): 539
Problem Description
sd0061, the legend of Beihang University ACM-ICPC Team, retired last year leaving a group of noobs. Noobs have no idea how to deal with
m
coming contests.
sd0061 has left a set of hints for them.
There are n noobs in the team, the i -th of which has a rating ai . sd0061 prepares one hint for each contest. The hint for the j -th contest is a number bj , which means that the noob with the (bj+1) -th lowest rating is ordained by sd0061 for the j -th contest.
The coach asks constroy to make a list of contestants. constroy looks into these hints and finds out: bi+bj≤bk is satisfied if bi≠bj, bi<bk and bj<bk .
Now, you are in charge of making the list for constroy.
There are n noobs in the team, the i -th of which has a rating ai . sd0061 prepares one hint for each contest. The hint for the j -th contest is a number bj , which means that the noob with the (bj+1) -th lowest rating is ordained by sd0061 for the j -th contest.
The coach asks constroy to make a list of contestants. constroy looks into these hints and finds out: bi+bj≤bk is satisfied if bi≠bj, bi<bk and bj<bk .
Now, you are in charge of making the list for constroy.
Input
There are multiple test cases (about
10
).
For each test case:
The first line contains five integers n,m,A,B,C . (1≤n≤107,1≤m≤100)
The second line contains m integers, the i -th of which is the number bi of the i -th hint. (0≤bi<n)
The n noobs' ratings are obtained by calling following function n times, the i -th result of which is ai .
For each test case:
The first line contains five integers n,m,A,B,C . (1≤n≤107,1≤m≤100)
The second line contains m integers, the i -th of which is the number bi of the i -th hint. (0≤bi<n)
The n noobs' ratings are obtained by calling following function n times, the i -th result of which is ai .
unsigned x = A, y = B, z = C; unsigned rng61() { unsigned t; x ^= x << 16; x ^= x >> 5; x ^= x << 1; t = x; x = y; y = z; z = t ^ x ^ y; return z; }
Output
For each test case, output "
Case #
x
:
y1
y2
⋯
ym
" in one line (without quotes), where
x
indicates the case number starting from
1
and
yi
(1≤i≤m)
denotes the rating of noob for the
i
-th contest of corresponding case.
Sample Input
3 3 1 1 1 0 1 2 2 2 2 2 2 1 1
Sample Output
Case #1: 1 1 202755 Case #2: 405510 405510
C++ STL中有一个库函数,nth_element。关于它的用法如下:
有了这个函数,我们只需要离线的对查询排序,然后对每个查询的值在不断分割的子区间上调用这个函数(实际上就和快速排序的实现差不多),这样就可有很少冗余度的得到我们所需要的答案。
这样写复杂度的显然是远小于快排的O(N * log N),详细的复杂度计算引用官方题解:
#include <algorithm>
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
using namespace std;
typedef long long LL;
const int N = 1e7+10;
unsigned a[N],ans[110];
int b[110], pos[110] ;
const LL mod = 1e9+7;
int A, B, C;
unsigned x, y, z;
unsigned rng61()
{
unsigned t;
x ^= x << 16;
x ^= x >> 5;
x ^= x << 1;
t = x;
x = y;
y = z;
z = t ^ x ^ y;
return z;
}
int cmp(int p,int q){return b[p]<b[q];}
int main()
{
int t, ncase=1;
int n, m;
while(scanf("%d %d %d %d %d", &n, &m, &A, &B, &C)!=EOF)
{
x=A,y=B,z=C;
for(int i=0;i<n;i++) a[i]=rng61();
for(int i=0;i<m;i++) scanf("%d", &b[i]),pos[i]=i;
sort(pos,pos+m,cmp);
b[m]=n,pos[m]=m;
for(int i=m-1;i>=0;i--)
{
if(b[pos[i]]==b[pos[i+1]]) ans[pos[i]]=ans[pos[i+1]];
else
{
nth_element(a,a+b[pos[i]],a+b[pos[i+1]]);
ans[pos[i]]=a[b[pos[i]]];
}
}
printf("Case #%d:",ncase++);
for(int i=0;i<m;i++) printf(" %u",ans[i]);
cout<<endl;
}
return 0;
}