Codeforces 900C - Remove Extra One(思維好題)

Remove Extra One
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output

You are given a permutation p of length n . Remove one element from permutation to make the number of records the maximum possible.
We remind that in a sequence of numbers a1,a2,...,ak the element ai is a record if for every integer j(1j<i) the following holds: aj<ai .

input
The first line contains the only integer n(1n105) — the length of the permutation.
The second line contains n integers p1,p2,...,pn (1pin) — the permutation. All the integers are distinct.

Output
Print the only integer — the element that should be removed to make the number of records the maximum possible. If there are multiple such elements, print the smallest one.

Examples
Input
1
1
Output
1
Input
5
5 1 2 3 4
Output
5

Note
In the first example the only element can be removed.

解題思路

先給一波官方題解:

In this problem you have to find an element after which removal the number of records is maximum possible.
Let ri be an array consisting of 0 and 1 depending on whether the ith element was a record initially or not. We can compute it easily in O(N) .
Let xi be the difference between the number of records after removal the i-th element and initial number of records.
Let’s think of how does removal of ai influence the array ri . First of all, ri becomes 0. rj(j<i) do not change in this case. Some of rj(j>i) , change from 0 to 1. These elements are not records initially, but become records after the removal. These elements are elements which have only one greater element in front of them — ai .
Here follows an O(n2) solution. Let’s fix ai — the element we are going to remove. Let xi=ri  +  the number of such j that j>i , ai>aj , and for all k(ki,k<j) ak<aj. We can compute this just looping through all j and keeping the maximum over all elements but the ith .
Now note that it’s not required to fix ai . rj can become 1 from 0 only when a certain element from the left is removed. Let’s loop through all aj and determine if there is an element to the left such that it is greater than aj , but all other elements are less than aj . We can check this using ordered set. If there is such a ai , then increase xi by 1. After the loop the array xi is fully computed, so we can just find the element which brings the maximum number of records, and minimum among such.

一個元素比它前面的所有元素都大,稱此元素爲record

首先用一個標記數組r[i] 表示第i個元素是(1)否(0)是record ,在O(N) 時間內可以求出。

然後考慮移除一個元素i 後,能影響哪些record

自身。還有:在他之後的,某些原本不是record 的,因爲i 的移除,成爲record 的。

這些record (稱爲j )有這樣的特點:比從1到j1i 外的元素都大,但不比i 大。

記從1到j1i 外的元素的最大值爲k ,則可表示爲k<j<=i 。此不等式爲本題“題眼”。

這樣就有了官方的O(N2) 解法:枚舉要移除的元素i ->檢查i 及在他之後的j ,計算record 增量->得移除後能使record 最大的元素。

然而BB半天,1e5 數據,顯然超時。

這時候想想“題眼”,那個神奇的不等式。

同樣設(刪除j 後的)增量數組x[j]O(N) 順推並維護ki 不就可以了?

如果j>i ,說明jrecordx[j] ,並更新jiki

如果k<j=<i ,“題眼”,x[i]++ (注意是i ),並更新kj

最後的問題,如果存在相同的元素,映射不唯一,一首涼涼?

回頭審題,distinct ,計劃通,代碼非常簡單。

小坑點,第一個元素是不算record 的。

AC代碼

#include<bits/stdc++.h>
using namespace std;

int a[100050];

int main()
{
    int n;
    while(cin>>n){
        memset(a,0,sizeof(a));
        int x,m2nd=0,m1st=0;
        for(int i=1;i<=n;i++){
            cin>>x;
            if(x>m1st){
                m2nd=m1st;
                m1st=x;
                a[x]--;
            }
            else if(x>m2nd){
                m2nd=x;
                a[m1st]++;
            }
        }
        int ma=-0x3f3f3f3f,mi;
        for(int i=1;i<=n;i++)
            if(a[i]>ma)
                ma=a[i],mi=i;
        printf("%d\n",mi);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章