Parallel search + multiset + double pointer cf982D

I feel that my solution is very complex and I have written a lot of code.

But the core is to enumerate the values of each element from small to large, and then merge the values of < = current element. Because this process is monotonous, you can directly merge the new elements into the old and query the set.

Maintain and query the set, maintain the size of each set, put the size in multiset, and then judge whether the size of each block is the same. If it is the same, update the answer.

#include<bits/stdc++.h>
#include<set>
using namespace std;
#define maxn 200005
int a[maxn],n;
struct Node {int pos,v;}p[maxn];

set<int>pq;
set<int>::iterator itt;
multiset<int>s;
multiset<int>::iterator it;

int cmp(Node a,Node b){return a.v<b.v;}

int f[maxn],size[maxn],vis[maxn];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void bing(int x,int y){
    x=find(x);y=find(y);
    if(x==y)return;
    s.erase(s.find(size[x]));
    s.erase(s.find(size[y]));
    f[x]=y;size[y]+=size[x];
    s.insert(size[y]);
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        pq.insert(a[i]);
        p[i].pos=i;p[i].v=a[i];
    }
    
    sort(p+1,p+1+n,cmp);
    for(int i=1;i<=n;i++)f[i]=i,size[i]=1;
    
    int Max=-1,ans,i=1;
    while(pq.size()){
        itt=pq.begin();
        int cur=*itt;pq.erase(itt);
        while(i<=n && p[i].v<=cur){//hold<=cur All values of are combined 
            int pos=p[i].pos;
            s.insert(1);vis[pos]=1; 
            if(pos>1 && a[pos-1]<=a[pos] && vis[pos-1])
                bing(pos-1,pos);
            if(pos<n && a[pos+1]<=a[pos] && vis[pos+1])
                bing(pos+1,pos);
            ++i;
        }
        int fir,end;
        it=s.begin();fir=*it;
        it=s.end();it--;end=*it;
        if(fir==end){
            if((double)Max<(double)s.size())
                Max=s.size(),ans=cur+1;
        }
    }
    cout<<ans<<endl;
} 

Keywords: PHP

Added by rdoylelmt on Tue, 29 Oct 2019 21:59:28 +0200