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; }
没有人不辛苦,只有人不喊疼