【Foreign】冒泡排序 [暴力]
冒泡排序
Time Limit: 10 Sec Memory Limit: 256 MBDescription
Input
Output
仅一行一个整数表示答案。
Sample Input
4 5 7 9 13
Sample Output
2
HINT
Main idea
按照题意生成排列,问要几轮冒泡排序可以让其有序(从小到大)。
Solution
首先我们先根据冒泡排序的性质来找个规律,因为一个数前面有几个数字比它大,这个数字就会向前移动几位,然后再回到自己的位置。
那么显然就是:设x表示在i位置前权值<Ai的数的个数,最大的x即是答案。
那么这个东西我们一眼就想到了70分(O(nlogn))就是用树状数组来倒叙打标记维护前缀和即可。
但是题目要求是O(n)的做法,怎么办呢?我们仔细推一下式子(打表)发现这个答案正是max(i-Ai),那么我们暴力扫一遍即可。
Code
1 #include<iostream>
2 #include<string>
3 #include<algorithm>
4 #include<cstdio>
5 #include<cstring>
6 #include<cstdlib>
7 #include<ctime>
8 #include<cmath>
9 using namespace std;
10 typedef long long s64;
11
12 const int ONE=30000001;
13
14 int n,S,B,C,D;
15 int A[ONE];
16 int Ans;
17
18 int get()
19 {
20 int res=1,Q=1;char c;
21 while( (c=getchar())<48 || c>57 )
22 if(c=='-')Q=-1;
23 res=c-48;
24 while( (c=getchar())>=48 && c<=57 )
25 res=res*10+c-48;
26 return res*Q;
27 }
28
29 int main()
30 {
31 n=get(); S=get(); B=get(); C=get(); D=get();
32 for(int i=1;i<=n;i++)
33 {
34 A[i]=i;
35 S=((s64)S*B+C) % D;
36 swap(A[i],A[(S%i)+1]);
37 }
38
39 for(int i=1;i<=n;i++)
40 {
41 Ans=max(Ans,i-A[i]);
42 }
43
44 printf("%d",Ans);
45 }