1. 程式人生 > >[簡單思維題]Sequence(山東省第九屆ACM大學生程序設計競賽E題)

[簡單思維題]Sequence(山東省第九屆ACM大學生程序設計競賽E題)

-o pri otto height ive 數量 nsis TP lin

Problem Description

We define an element a_iai? in a sequence "good", if and only if there exists a j(1\le j < i)j(1j<i) such that a_j < a_iaj?<ai?.
Given a permutation pp of integers from 11 to nn. Remove an element from the permutation such that the number of "good" elements is maximized.

Input

The input consists of several test cases. The first line of the input gives the number of test cases, T(1\le T\le 10^3)T(1T103).
For each test case, the first line contains an integer n(1\le n\le 10^6)n(1n106), representing the length of the given permutation.
The second line contains nn integers p_1,p_2,\cdots,p_n(1\le p_i\le n)p1?,p2?,?,pn?(1pi?n), representing the given permutation pp.

It’s guaranteed that \sum n\le 2\times 10^7n2×107.

Output

For each test case, output one integer in a single line, representing the element that should be deleted. If there are several answers, output the minimal one.

Sample Input

2
1
1
5
5 1 2 3 4

Sample Output

1
5

思路:首先要明白,一個不好數,它總是它之前(包括它)出現的所有數中最小的;
考慮刪的刪除一個好數還是不好數:
刪除一個好數,則總的好數數量將減少一個(因為刪除它後能影響到的好數僅有它自己);
刪除一個不好數,考慮刪除這個不好數後能影響到的好數有幾個,那麽總的好數數量就減少幾個;(被它所影響到的好數(假設目前考慮的好數是a[i])是那些滿足 最小{a[0~1-i]}<a[i]<=次小{a[0~n-1]} 的數)
AC代碼:
#include <iostream>
#include<cstdio>
#include<algorithm>
typedef long long ll;
#define inf 0x3f3f3f3f
using namespace std;

ll a[1000010];
ll first[1000010];
ll second[1000010];
bool flag[1000010];
ll cnt[1000010];

int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--){
        ll n;
        scanf("%lld",&n);
        ll now_min=inf;ll pre_min=inf;
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            first[i]=now_min; second[i]=pre_min;
            //維護前綴最小和前綴次小
            if(a[i]<=now_min) {pre_min=now_min; now_min=a[i];}
            else {if(a[i]<pre_min) pre_min=a[i];}
        }
        for(ll i=1;i<=n;i++){//不好數標記為1,好數標記為0
            if(a[i]<=first[i]) flag[i]=1;
            else flag[i]=0;
        }
        ll k;
        for(ll i=1;i<=n;i++){
            if(flag[i]==1){
                k=i;
                cnt[k]=0;
            }
            else{
                if(a[i]<=second[i]) cnt[k]++;
            }
        }
        ll ans=inf;
        for(ll i=1;i<=n;i++){
            if(flag[i]==1&&cnt[i]==0) ans=min(ans,a[i]);
        }
        if(ans==inf) {
            for(ll i=1;i<=n;i++){
              if(flag[i]==0) ans=min(ans,a[i]);
              else if(cnt[i]==1) ans=min(ans,a[i]);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

過了此題是真的開心~~~,要多思考啊

技術分享圖片

[簡單思維題]Sequence(山東省第九屆ACM大學生程序設計競賽E題)