CF899E Segments Removal(set+优先队列)

合并显然可以想到使用双向链表,而对于如何找到最大值,可以用优先队列,两重排序。

有一些细节就是涉及到合并,合并完后需要将原有的两个状态删除,但是优先队列做不到,因此用set记录一下

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int nxt[N],last[N];
priority_queue<pll> q;
int cnt[N],num[N];
set<pll> s;
int a[N];
int main(){
    ios::sync_with_stdio(false);
    int i;
    int n;
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];
    int idx=1;
    int top=0;
    for(i=1;i<=n;i++){
        if(a[i]==a[i+1]){
            idx++;
        }
        else{
            num[++top]=idx,cnt[top]=a[i];
            idx=1;
        }
    }
    for(i=1;i<=top;i++){
        nxt[i]=i+1;
        last[i]=i-1;
        q.push({num[i],-i});
    }
    int res=0;
    while(top){
        while(q.size()&&s.count(q.top())){
            q.pop();
        }
        auto t=q.top();
        q.pop();
        int x=-t.second;
        int t1=last[x],t2=nxt[x];
        nxt[t1]=t2;last[t2]=t1;
        if(t1&&cnt[t1]==cnt[t2]){
            s.insert({num[t1],-t1});
            s.insert({num[t2],-t2});
            num[t1]+=num[t2];
            nxt[t1]=nxt[t2];
            last[nxt[t2]]=t1;
            q.push({num[t1],-t1});
            top--;
        }
        top--;
        res++;
    }
    cout<<res<<endl;
    return 0;
}
View Code

 

posted @ 2020-08-28 17:01  朝暮不思  阅读(259)  评论(0编辑  收藏  举报