OvO http://codeforces.com/contest/899/problem/E

  Codeforces Round #452 (Div. 2) - e

  899E

  用两个并查集(记为fa和ma),

  fa用于更新可以合并在一起的段,维护每个段的左端点,右端点,中间有多少个相同的值,和这个段的值得是什么,

  ma用于跳跃, 

  具体来说

  例如

  

  这组数据

  标上序号(第三行是序号)

  

  1.那么首先合并4个5(10-13),显然9所在的段和14所在的段不能合并

   那么把13指向9( ma[13]=9 ) 然后把10指向14( ma[10]=14 )

  2.然后合并3个4( 7-9 ),判断合并的两个位置记为a和b,首先a=6,b本来等于10,然后通过并查集ma更改b=14,显然不能合并

   那么同样 ma[7]=10, ma[9]=6

  3.然后合并3个6( 14-16 ),判断合并的位置是 a=13 和 b=17 ,通过并查集ma更改a=6

   显然 a 所在段的值和 b 所在段的值是一样的,而且a和b所在段都未处理过,通过fa并查集处理 a 和 b 找到 a ,b在fa并查集的祖先,就可以合并a和b所在段。

  对于寻找哪个段最长的话,通过一个保存段长度的优先队列来查找

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue> using namespace std; const int M=2e5+44; struct Node
{
int id,num,li,ri,cnt;
friend bool operator<(Node x,Node y)
{
if(x.cnt==y.cnt) return x.id>y.id;
return x.cnt<y.cnt;
}
} p[M]; priority_queue<Node> que;
int n,fa[M],ma[M]; int fff(int rt)
{
if(fa[rt]==rt)
return rt;
return fa[rt]=fff(fa[rt]);
} int emm(int rt)
{
if(ma[rt]==rt)
return rt;
return ma[rt]=emm(ma[rt]);
} void merge(int a,int b,int flag)
{
if(a<1 || b>n)
return ;
int qa=emm(a),qb=emm(b);
int qqa=fff(qa),qqb=fff(qb);
if(p[qa].num!=p[qb].num || p[qqa].cnt==-1 || p[qqb].cnt==-1)
{
int xa=a+1,xb=b-1;
ma[xb]=a; ma[xa]=b;
return ;
}
int pa=qqa,pb=qqb;
fa[pb]=pa;
p[pa].cnt+=p[pb].cnt,p[pa].li=min(p[pa].li,p[pb].li),p[pa].ri=max(p[pa].ri,p[pb].ri);
p[pb].cnt=-1;
if(flag)
que.push(p[pa]);
} int main()
{
Node now;
int nowid,ans;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&p[i].num);
p[i].id=i; p[i].li=p[i].ri=i; p[i].cnt=1;
fa[i]=i; ma[i]=i;
}
for(int i=2;i<=n;i++)
if(p[i].num==p[i-1].num)
merge(i-1,i,0);
while(!que.empty())
que.pop();
for(int i=1;i<=n;i++)
if(p[i].cnt!=-1)
que.push(p[i]);
ans=0;
while(!que.empty())
{
now=que.top(); que.pop();
nowid=now.id;
if(p[nowid].cnt!=now.cnt) continue;
// cout<<p[nowid].li<<' '<<p[nowid].ri<<' '<<p[nowid].num<<endl;
ans++; p[nowid].cnt=-1;
merge(now.li-1,now.ri+1,1);
}
printf("%d\n",ans);
return 0;
} /* 19
1 1 2 2 3 3 4 4 4 5 5 5 5 6 6 6 3 2 1 */

  

  

Codeforces Round #452 (Div. 2) 899E E. Segments Removal的更多相关文章

  1. Codeforces Round #452 (Div. 2) A B C

    Codeforces Round #452 (Div. 2) A Splitting in Teams 题目链接: http://codeforces.com/contest/899/problem/ ...

  2. Codeforces Round #448 (Div. 2) B. XK Segments【二分搜索/排序/查找合法的数在哪些不同区间的区间数目】

    B. XK Segments time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  3. Codeforces Round #452 (Div. 2)-899A.Splitting in Teams 899B.Months and Years 899C.Dividing the numbers(规律题)

    A. Splitting in Teams time limit per test 1 second memory limit per test 256 megabytes input standar ...

  4. Codeforces Round #452 (Div. 2) C. Dividing the numbers(水)

    C. Dividing the numbers Petya has n integers: 1, 2, 3, ..., n. He wants to split these integers in t ...

  5. Codeforces Round #452 (Div. 2)

    第一次打..(太弱(+99积分是几个意思 A 题意:一堆数,只有1和2,问最多凑出多少个3. 分情况即可 #include<cstdio> int main(){ int a=0,b=0, ...

  6. 【Codeforces Round #455 (Div. 2) B】Segments

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 处理出所有的线 其实就是区间. 总共有n*(n+1)/2个 然后按照左端点.右端点排序 每次取最左边的线. 多种可能就取右端点尽量小 ...

  7. 【Codeforces Round #452 (Div. 2) A】 Splitting in Teams

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 贪心 1优先和2组队. 如果1没有了 就结束. 如果1还有多余的. 那么就自己3个3个组队 [代码] #include <bi ...

  8. 【Codeforces Round #452 (Div. 2) B】Months and Years

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 闰,平,平 平,闰,平 平,平,闰 平,平,平 4种情况都考虑到就好. 可能有重复的情况. 但是没关系啦. [代码] #includ ...

  9. 【Codeforces Round #452 (Div. 2) C】 Dividing the numbers

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] n为偶数. l = 1, r = n (l,r)放在一组 l++,r-- 新的l,r放在另外一组 直到l+1==r 这个时候,判断两 ...

随机推荐

  1. 飞腾1500A 上面银河麒麟操作系统 进行远程以及添加用户的方法 linux xrdp

    1. 安装远程用的软件: sudo apt-get install xrdp vnc4server xbase-clients systemctl enable xrdp systemctl star ...

  2. Python Excel文件的读写操作(xlwt xlrd xlsxwriter)

    转:https://www.cnblogs.com/ultimateWorld/p/8309197.html Python语法简洁清晰,作为工作中常用的开发语言还是很强大的(废话). python关于 ...

  3. DISCO Presents Discovery Channel Code Contest 2020 Qual Task E. Majority of Balls

    Not able to solve this problem during the contest (virtual participation). The first observation is ...

  4. 【深入浅出-JVM】(9): 方法区

    概念 方法区是虚拟机规范定义的,是所有线程共享的内存区域,保存系统的类的信息.比如:类的字段.方法.常量池.构造函数的字节码内容.代码.JIT 代码 永久代.metaspace 是对方法区的实现. H ...

  5. S03_CH02_AXI_DMA PL发送数据到PS

    S03_CH02_AXI_DMA PL发送数据到PS 1.1概述 本课程的设计原理分析. 本课程循序渐进,承接<S03_CH01_AXI_DMA_LOOP 环路测试>这一课程,在DATA ...

  6. DVWA漏洞演练平台 - 文件上传

    DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助w ...

  7. 使用canal获取mysql的binlog传输给kafka,并交由logstash获取实验步骤

    1. 实验环境 CPU:4 内存:8G ip:192.168.0.187 开启iptables防火墙 关闭selinux java >=1.5 使用yum方式安装的java,提前配置好JAVA_ ...

  8. 怎样理解 display:none 和 visibility:hidden

    1. display: none会使元素节点 "消失" , 就像 死亡后灰飞烟灭了. 它是不占位置的. 2. visibility: hidden会使元素节点 "隐藏&q ...

  9. 【转】js中的原型

    原文链接:https://blog.csdn.net/u012468376/article/details/53121081 一.什么是原型原型是Javascript中的继承的基础,JavaScrip ...

  10. Nginx安装与配置【转】

    原文:linux之nginx 作者;海燕. 一.nginx Ngix是web服务器,跟apache一样,它可以做动态请求转发.web端负载均衡.反向代理等等: tomcat是应用服务器,当然如果非用逼 ...