E. Segments Removal(优先队列&set)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了E. Segments Removal(优先队列&set)相关的知识,希望对你有一定的参考价值。
E. Segments Removal(优先队列&set)
本题可用优先队列模拟,用 p a i r pair pair储存每段长度和编号,然后开两个数组 n e x t [ ] , p r e [ ] next[],pre[] next[],pre[]用来合并操作。至于合并后之前的两个已经被删除的段怎么处理,考虑用 s e t set set标记是否访问即可,或者也可以再开一个优先队列维护。
两pq+链表
// Problem: E. Segments Removal
// Contest: Codeforces - Codeforces Round #452 (Div. 2)
// URL: https://codeforces.ml/problemset/problem/899/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Date: 2021-08-25 23:29:48
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int n;
priority_queue<PII>q,vis;
int nt[N],pre[N];
int a[N],b[N],cnt;
int main(){
scanf("%d",&n);
rep(i,1,n){
int x;scanf("%d",&x);
if(a[cnt]==x) b[cnt]++;
else a[++cnt]=x,b[cnt]=1;
}
rep(i,1,cnt) q.push({b[i],-i}),nt[i]=i+1,pre[i]=i-1;
int ans=0;
while(cnt){
while(!vis.empty()&&q.top()==vis.top()) q.pop(),vis.pop();
int x=-q.top().se;q.pop();
int u=pre[x],v=nt[x];
nt[u]=v,pre[v]=u;
if(u&&a[u]==a[v]){
vis.push({b[u],-u}),vis.push({b[v],-v});
b[u]+=b[v],nt[u]=nt[v],pre[nt[v]]=u;
q.push({b[u],-u});
cnt--;
}
cnt--;ans++;
}
printf("%d\\n",ans);
return 0;
}
pq+set
// Problem: E. Segments Removal
// Contest: Codeforces - Codeforces Round #452 (Div. 2)
// URL: https://codeforces.ml/problemset/problem/899/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Date: 2021-08-25 23:29:48
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define IOS ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int n;
priority_queue<PII>q;
set<PII>vis;
int nt[N],pre[N];
int a[N],b[N],cnt;
int main(){
scanf("%d",&n);
rep(i,1,n){
int x;scanf("%d",&x);
if(a[cnt]==x) b[cnt]++;
else a[++cnt]=x,b[cnt]=1;
}
rep(i,1,cnt) q.push({b[i],-i}),nt[i]=i+1,pre[i]=i-1;
int ans=0;
while(cnt){
while(vis.count(q.top())) q.pop();
int x=-q.top().se;q.pop();
int u=pre[x],v=nt[x];
nt[u]=v,pre[v]=u;
if(u&&a[u]==a[v]){
vis.insert({b[u],-u}),vis.insert({b[v],-v});
b[u]+=b[v],nt[u]=nt[v],pre[nt[v]]=u;
q.push({b[u],-u});
cnt--;
}
cnt--;ans++;
}
printf("%d\\n",ans);
return 0;
}
以上是关于E. Segments Removal(优先队列&set)的主要内容,如果未能解决你的问题,请参考以下文章
E. Carrots for Rabbits(贪心+优先队列)
E. Carrots for Rabbits(贪心+优先队列)
E. Carrots for Rabbits(贪心+优先队列)