【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出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...
随机推荐
- inside、outside和dmz之间的访问
现有条件:100M宽带接入,分配一个合法的IP(222.134.135.98)(只有1个静态IP是否够用?);Cisco防火墙PiX515e-r-DMZ-BUN1台(具有Inside.Outside. ...
- CentOS7安装.NET Core运行环境
安装.NET Core ->首先需要删除以前安装的版本 -> 获取安装脚本 curl -sSL https://raw.githubusercontent.com/dotnet/cli/r ...
- Java ISO 8601时间格式转换
common-lang包: String pattern = "YYYY-MM-dd'T'HH:mm:ssZZ"; System.out.println(DateFormatUti ...
- java网络编程(二)可中断套接字
参考资料:java核心技术 卷II 为中断套接字操作,可使用java.nio包提供的SocketChannel类.可以使用如下方式打开SocketChannel: SocketChannel chan ...
- Simple上网导航--静态版
现在的网址导航显然是一个针对小白用户的网页大全,新闻.笑话.视频.黄段子要什么有什么,一个网址导航竟然也要滑动好多页.其实80%的功能我都用不到,但是它们却时刻展现在我的眼前.所以我决定做一个简洁清晰 ...
- Eclipse中使用git提交代码,报错Testng 运行Cannot find class in classpath的解决方案
一.查找原因方式 1.点击Project——>Clear...——>Build Automatically 2.查看问题 二.报错因素 1.提交.xlsx文件 2.提交时,.xlsx文件被 ...
- 卷积 & 杜教筛
目录 卷积 杜教筛 前言:发现最近都没怎么写博客,,,赶紧发篇以前记的笔记凑凑数 卷积 卷积定义: 如果有数论函数\(f, g\), 那么它们卷积的第\(n\)项为\((f * g) (n)\),设这 ...
- [NOIP2008]双栈排序 【二分图 + 模拟】
题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...
- 转载乙醇大师的appium简明教程
appium简明教程(11)——使用resource id定位(仅支持安卓4.3以上系统) 乙醇 2014-06-28 21:01 阅读:16406 评论:21 appium简明教程(10)——控件定 ...
- bzoj3173: [Tjoi2013]最长上升子序列(fhqtreap)
这题用fhqtreap可以在线. fhqtreap上维护以i结尾的最长上升子序列,数字按从小到大加入, 因为前面的数与新加入的数无关, 后面的数比新加入的数小, 所以新加入的数对原序列其他数的值没有影 ...