【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出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...
随机推荐
- 3dContactPointAnnotationTool开发日志(三二)
今天就是看怎么把论文的python源码预测出来的smpl模型的姿势和形状参数弄到unity版本的smpl里,但是python版本的和unity版本的不一样. 先看看他的fit_3d.py: ...
- 使用.bat文件运行ant的build.xml
1.新建一个txt文件 2.复制下面命令到txt文件 echo "Start build..." call ant.bat -f "E:\build.xml" ...
- mac下面安装Navicat Premium 12.0.24 for mac已破解中文亲测可用
链接:https://pan.baidu.com/s/17HQ7dsCun2cSJGRpdP9yXA 密码:hwq5 Navicat_Premium_mac 最新版 12.0.24(原版是英文的) ...
- 修改Oracle redo.log文件的大小
1.查看当前日志组成员: SQL> select member from v$logfile; MEMBER ------------------------------------------ ...
- Linux服务器开启tomcat的gc日志
压力测试,为了能监控长期对gc的变化的情况,那么就需要在tomcat中进行配置相关的gc输入日志,以便后续来对gc中进行分析 工具 :linux+tomcat 1.进入到了tomcat的bin的目录下 ...
- css 层加透明度后文字依然清晰
background: rgba(, , , !important; /*实现FF背景透明,文字不透明*/ filter: Alpha(opacity=); background: #0a0a0a; ...
- python的N个小功能(高斯模糊原理及实践)
原理: 二维高斯函数 1) 为了计算权重矩阵,需要设定σ的值.假定σ=1.5,则模糊半径为1的权重矩阵如下: 2) 这9个点的权重总和等于0.4787147,如果只计算 ...
- 多线程---handlerthread
当我们需要工作线程来操作的时候,很多时候会有同步问题,UI更新问题. Handle机制就是为了解决这个问题而产生的. android允许每个线程都有自己的消息队列,同时也可以是主线程消息队列. 但是很 ...
- BZOJ3566 SHOI2014概率充电器(动态规划+概率期望)
设f[i]为i在子树内不与充电点连通的概率.则f[i]=(1-pi)·∏(1-qk+qk·f[k]). 然后从父亲更新答案.则f[i]=f[i]·(1-qfa+qfa*f[fa]/(1-qfa+qfa ...
- Django字段类型介绍
一,通过makemigrations,migrate来修改数据, 1.Django的ORM支持修改表结构,修改完以后,执行 python manage.py makemigrations pytho ...