【CodeForces】899 E. Segments Removal
【题意】给定n个数字,每次操作删除最长的连续相同数字(等长删最左),求全部删完的最少次数。n<=2*10^6,1<=ai<=10^9。
【算法】并查集+堆
【题解】将序列的相同数字段压缩,全部插入堆。那么每次操作删除堆顶,并尝试合并堆顶的前驱和后继,能合并就重新插入堆中。
在支持删除的序列中找前驱和后继,是经典的并查集实现。
具体而言,fa[i]表示 i 点左边(含自身)最近的未被删除的点,即把删除了的点全部并入左侧第一个未被删除的点,那么删除点x后fa[x]=find(fa[x]-1)。
前驱是find(fa[x]-1),后继只需要记录r[x]表示x点代表区间的最右端点,每次合并是:fa[y]=x,r[x]=r[y]。
如果能合并就重新插入堆中,容易发现堆中废弃的元素一定比新插入的更晚访问,所以废弃元素访问到就会是被删除的现象,一个元素被删除表现为find(x) ≠ x。
注意:删除的时候记得更新r[]。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define ll long long
#define lowbit(x) x&-x
using namespace std;
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a<b?b:a;}
int ab(int x){return x>?x:-x;}
//int MO(int x){return x>=MOD?x-MOD:x;}
//void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=; int n,fa[maxn],a[maxn],tot,r[maxn];
struct cyc{
int id,ans,number,l;
bool operator < (const cyc &a)const{
return ans<a.ans||(ans==a.ans&&l>a.l);
}
}b[maxn];
priority_queue<cyc>q;
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int main(){
n=read();
int x=;
for(int i=;i<=n;i++)a[i]=read();
for(int i=;i<=n;i++){
x++;
if(a[i]!=a[i+]){
b[++tot]=(cyc){tot,x,a[i],i};
x=;
}
}
n=tot;
for(int i=;i<=n;i++)fa[i]=i,r[i]=i;
for(int i=;i<=n;i++)q.push(b[i]);
for(int i=;i<=n;i++){
cyc x=q.top();q.pop();
while(find(x.id)!=x.id&&!q.empty())x=q.top(),q.pop();
if(q.empty()){if(find(x.id)!=x.id)printf("%d",i-);else printf("%d",i);return ;}
//printf("%d %d %d %d\n",x.id,x.ans,x.number,x.l);
int f=find(x.id);
fa[f]=find(f-);r[fa[f]]=r[f];
int pre=find(f-),suc=find(r[f]+);
if(pre==||suc==||b[pre].number!=b[suc].number)continue;
fa[suc]=pre;
b[pre].ans+=b[suc].ans;
r[pre]=r[suc];
q.push(b[pre]);
}
return ;
}
【CodeForces】899 E. Segments Removal的更多相关文章
- 【CodeForces】899 F. Letters Removing
[题目]F. Letters Removing [题意]给定只含小写字母.大写字母和数字的字符串,每次给定一个范围要求删除[l,r]内的字符c(l和r具体位置随删除变动),求m次操作后的字符串.n&l ...
- 【CodeForces】901 C. Bipartite Segments
[题目]C. Bipartite Segments [题意]给定n个点m条边的无向连通图,保证不存在偶数长度的简单环.每次询问区间[l,r]中包含多少子区间[x,y]满足只保留[x,y]之间的点和边构 ...
- 【Luogu3602】Koishi Loves Segments(贪心)
[Luogu3602]Koishi Loves Segments(贪心) 题面 洛谷 题解 离散区间之后把所有的线段挂在左端点上,从左往右扫一遍. 对于当前点的限制如果不满足显然会删掉右端点最靠右的那 ...
- 【CF429E】Points and Segments(欧拉回路)
[CF429E]Points and Segments(欧拉回路) 题面 CF 洛谷 题解 欧拉回路有这样一个性质,如果把所有点在平面内排成一行,路径看成区间的覆盖,那么每个点被从左往右的覆盖次数等于 ...
- 【CF429E】Points and Segments 欧拉回路
[CF429E]Points and Segments 题意:给你数轴上的n条线段$[l_i,r_i]$,你要给每条线段确定一个权值+1/-1,使得:对于数轴上的任一个点,所有包含它的线段的权值和只能 ...
- 【Codeforces】Round #491 (Div. 2) 总结
[Codeforces]Round #491 (Div. 2) 总结 这次尴尬了,D题fst,E没有做出来.... 不过还好,rating只掉了30,总体来说比较不稳,下次加油 A:If at fir ...
- 【Codeforces】Round #488 (Div. 2) 总结
[Codeforces]Round #488 (Div. 2) 总结 比较僵硬的一场,还是手速不够,但是作为正式成为竞赛生的第一场比赛还是比较圆满的,起码没有FST,A掉ABCD,总排82,怒涨rat ...
- 【CodeForces】601 D. Acyclic Organic Compounds
[题目]D. Acyclic Organic Compounds [题意]给定一棵带点权树,每个点有一个字符,定义一个结点的字符串数为往下延伸能得到的不重复字符串数,求min(点权+字符串数),n&l ...
- 【Codeforces】849D. Rooter's Song
[算法]模拟 [题意]http://codeforces.com/contest/849/problem/D 给定n个点从x轴或y轴的位置p时间t出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...
随机推荐
- 七周七语言之使用prolog解决爱因斯坦斑马难题
如果你想获得更好的阅读体验,可以前往我在 github 上的博客进行阅读,http://lcomplete.github.io/blog/2013/06/28/sevenlang-prolog/. 目 ...
- 第八次java笔记
- PAT 甲级 1081 Rational Sum (数据不严谨 点名批评)
https://pintia.cn/problem-sets/994805342720868352/problems/994805386161274880 Given N rational numbe ...
- PAT 甲级 1027 Colors in Mars
https://pintia.cn/problem-sets/994805342720868352/problems/994805470349344768 People in Mars represe ...
- PAT 甲级 1050 String Subtraction
https://pintia.cn/problem-sets/994805342720868352/problems/994805429018673152 Given two strings S~1~ ...
- 爬虫学习之-urlparse之urljoin()
首先导入模块,用help查看相关文档 >>> from urlparse import urljoin >>> help(urljoin) Help on func ...
- [翻译]API Guides - Service
官方文档原文地址:http://developer.android.com/guide/components/services.html Service是应用程序组件之一,它并不提供一个用户界面,可以 ...
- libmnl
https://www.netfilter.org/projects/libmnl/doxygen/modules.html 1,tar xvf libmnl-1.0.4.tar.gz 2,cd li ...
- HDU4055_Number String
题目告诉你在一个排列中,相邻两个数的大小关系.问你排列可能有多少种情况. DP. f[i][j]表示将i个数按照前面i-1个大小关系排列且最后一个数位j的排列数有多少个. 这样对于新加入的一个数i+1 ...
- hihocoder 1828 Saving Tang Monk II (DP+BFS)
题目链接 Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great C ...