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 (1 ≤ j < i) the following holds: aj < ai.
The first line contains the only integer n (1 ≤ n ≤ 105) — the length of the permutation.
The second line contains n integers p1, p2, ..., pn (1 ≤ pi ≤ n) — the permutation. All the integers are distinct.
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.
1 1
1
5 5 1 2 3 4
5
In the first example the only element can be removed.
题意:
删除一个数使得record的个数最大;
思路:
用了个比较麻烦的想法,维护了两个线段树。。。我们知道只有左边比当前位置大的数只有一个的时候,我们才有可能去考虑他,所以我们把这些只有一个的数比他大都保存起来,然后枚举删哪个数,根据能增加的价值去更新。。还有一些细节,看代码吧
#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn = 1e5+5;
int sum[maxn<<2];
int sum2[maxn<<2];
int a[maxn];
int n;
void push_up(int rt)
{
sum[rt] = sum[lson] +sum[rson];
sum2[rt] = sum2[lson]+sum2[rson];
}
int query(int l,int r,int L,int R,int rt)
{
if(L<=l&&R>=r){
return sum[rt];
}
int mid = (l+r)>>1;
int ret = 0;
if(L<=mid){
ret += query(l,mid,L,R,lson);
}
if(mid<R){
ret += query(mid+1,r,L,R,rson);
}
return ret;
}
int query2(int l,int r,int L,int R,int rt)
{
if(L<=l&&R>=r){
return sum2[rt];
}
int mid = (l+r)>>1;
int ret = 0;
if(L<=mid){
ret += query2(l,mid,L,R,lson);
}
if(mid<R){
ret += query2(mid+1,r,L,R,rson);
}
return ret;
}
void update(int pos,int va,int l,int r,int rt)
{
if(l==r&&r==pos)
{
sum[rt]+= va;
return ;
}
int mid = (l+r)>>1;
if(pos<=mid){
update(pos,va,l,mid,lson);
}
else{
update(pos,va,mid+1,r,rson);
}
push_up(rt);
}
void update2(int pos,int va,int l,int r,int rt)
{
if(l==r&&r==pos)
{
sum2[rt]+= va;
return ;
}
int mid = (l+r)>>1;
if(pos<=mid){
update2(pos,va,l,mid,lson);
}
else{
update2(pos,va,mid+1,r,rson);
}
push_up(rt);
}
void update3(int pos,int l,int r,int rt)
{
if(l==r&&r==pos)
{
sum2[rt] = 0;
return ;
}
int mid = (l+r)>>1;
if(pos<=mid){
update3(pos,l,mid,lson);
}
else{
update3(pos,mid+1,r,rson);
}
push_up(rt);
}
int vis[maxn];
int main(){
while(~scanf("%d",&n))
{
memset(vis,0,sizeof(vis));
memset(sum2,0,sizeof(sum2));
memset(sum,0,sizeof(sum));
int mx = -1;
int ans;
for(int i = 1;i<=n;i++){
scanf("%d",&a[i]);
int tmp = query(1,n,a[i]>=n?a[i]:a[i]+1,n,1);
// cout<<tmp<<' '<<i<<endl;
if(tmp==1){
update2(a[i],1,1,n,1);
}
else if(tmp==0){
vis[i] = 1;
}
update(a[i],1,1,n,1);
}
for(int i = 1;i<=n;i++)
{int tmp;
if(vis[i]==0){
tmp = 0;
}
else{
if(a[i]==1){
tmp = 0;
}
else
tmp = query2(1,n,1,a[i]-1,1);
// cout<<tmp<<' ';
tmp-=vis[i]?1:0;
}
// cout<<tmp<<' '<<a[i]<<endl;
if(tmp>mx){
mx =tmp;
ans = a[i];
}
else if(tmp==mx){
ans = min(ans,a[i]);
}
update3(a[i],1,n,1);
}
cout<<ans<<endl;
}
}