HBCPC 2018 网络赛H 【分块】

H. GSS and OJ Submissions
time limit per test
6 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

GSS is holding a large programming contest on the website called EOJ or compileError Online Judge which is the largest programming contest platform in the world. Every day, millians of codes are submitted to the platform.

One day, someone submitted the n-th code (1 ≤ n ≤ 4 × 108), where n is GSS's lucky number, to celebrate this day, GSS is going to send a huge prize. In this case, he allocated every submission a number in [0, 264) (see the paragraph below), then he generate another number L in [1, n] . The user who submitted the submission with the L-th small number will receive the prize.

GSS allocate numbers to submissions in the following way:

typedef unsigned long long ull;
void allocate(ull A, ull B, ull s0, ull s[])
{
    s[0] = s0;
    for (int i = 1; i < n; i++) {
        s[i] = s[i - 1] * A + B;
    }
}

AB and s0 are generated elsewhere, and 0 ≤ A, B, s0 < 264. And you can assume that A, B and s0 are generated in random.

Special notice: the code above will comsume about 2 seconds or more on judger.

Now, Mingming have collected all numbers allocated to his submissions, and he wants to know weather he will win the prize. But he is too lazy to solve, so he asked you for help, please, tell him the number allocated to the submission which win the prize.

Input

Input contains 5 integers, A, B, L, n, s0.

Output

Output one line with the number —— the number allocated to the submission which win the prize.

Example
input
Copy
5 7 9 11 13
output
Copy
5761717
Note

The numbers allocated to submissions are:

13, 72, 367, 1842, 9217, 46092, 230467, 1152342, 5761717, 28808592, 144042967

it is clear that the ninth one is 5761717.

题意:给4e8个unsigned long long范围内整数,求其第l大数为多少?

分析:4e8个数,利用分块算法将其分成N块,块与块之间存在绝对的大小关系,就能间接的快速比较,然后在块内求出第l大。

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const LL NV=1e14+1;
int num[200010];
LL A,B,s,s0,b[50000];
int n,l,k;
int main()
{
    while(scanf("%llu%llu%d%d%llu",&A,&B,&l,&n,&s)!=EOF)
    {
        for(int i=1;i<=200000;i++)num[i]=0;
        s0=s;
        for(int i=1;i<=n;i++)
        {
            num[s0/NV]++;
            s0=s0*A+B;
        }
        for(int i=0;i<200000;i++)
        {
            if(l>num[i])
                l-=num[i];
            else
            {
                k=i;
                break;
            }
        }
        s0=s;
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            if(k==s0/NV)
                b[++cnt]=s0;
            s0=s0*A+B;
        }
        sort(b+1,b+cnt+1);
        printf("%I64d\n",b[l]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37953323/article/details/79954686
今日推荐