【Foreign】冒泡排序 [暴力]

时间:2023-03-09 02:24:09
【Foreign】冒泡排序 [暴力]

冒泡排序

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

  【Foreign】冒泡排序 [暴力]

Input

  【Foreign】冒泡排序 [暴力]

Output

  仅一行一个整数表示答案。

Sample Input

  4 5 7 9 13

Sample Output

  2

HINT

  【Foreign】冒泡排序 [暴力]

Main idea

  按照题意生成排列,问要几轮冒泡排序可以让其有序(从小到大)。

Solution

  首先我们先根据冒泡排序的性质来找个规律,因为一个数前面有几个数字比它大,这个数字就会向前移动几位,然后再回到自己的位置。

  那么显然就是:x表示在i位置前权值<Ai的数的个数,最大的x即是答案

  那么这个东西我们一眼就想到了70分(O(nlogn))就是用树状数组来倒叙打标记维护前缀和即可。

  但是题目要求是O(n)的做法,怎么办呢?我们仔细推一下式子(打表)发现这个答案正是max(i-Ai),那么我们暴力扫一遍即可。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE=; int n,S,B,C,D;
int A[ONE];
int Ans; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} int main()
{
n=get(); S=get(); B=get(); C=get(); D=get();
for(int i=;i<=n;i++)
{
A[i]=i;
S=((s64)S*B+C) % D;
swap(A[i],A[(S%i)+]);
} for(int i=;i<=n;i++)
{
Ans=max(Ans,i-A[i]);
} printf("%d",Ans);
}