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. mysql中的反引号``

    [1]反引号`,数字1左边的符号.tab键上面的符号. 它是为了区分MYSQL的保留字与普通字符而引入的符号. 不加反引号建的表不能包含MYSQL保留字,否则出错 如上图,很明显的,如果我们直接建立名 ...

  2. Python+requests 发送简单请求--》获取响应状态--》获取请求响应数据

    Python+requests 发送简单请求-->获取响应状态-->获取请求响应数据 1.环境:安装了Python和vscode编译器(Python自带的编译器也ok).fiddler抓包 ...

  3. phpstorm右侧边栏怎么打开?

    开启PHPstorm右侧边栏的方法: 一般phpstorm默认只能打开10个文件,超过就隐藏了,想要打开更多:

  4. 适合新手的160个creakme(二)

    先跑一下,然后找出关键字符串 关键字符串是You Get Wrong和Try Again,不过IDA好像识别不出来这个字符串,在Ollydbg中右键Search For,寻找所有字符串,可以找到这些字 ...

  5. Creating mailbox file: 文件已存在

    原来linux下添加用户后,会在系统里自动加一个邮箱(系统邮箱),路径是:/var/spool/mail/用户名.可以直接用命令#rm -rf /var/spool/mail/用户名 这样就可以再次添 ...

  6. 关于BIOS系统的认识和学习(源自摘录)

    BIOS系统的介绍与学习 BIOS (basic input output system 即基本输入输出系统)在计算机系统中起着非常重要的作用,其是计算机系统最底层的设置, BIOS设置程序是被固化到 ...

  7. 彭博社:博通正在与赛门铁克洽谈收购事宜(博通能买得起 又能讲故事的 没几个了 为了刺激资本的兴趣 只能瞎搞 就和intel 收购 麦咖啡一样。就像杜蕾斯收购美赞臣一样,也许只是纯粹的商业行为,哪行赚钱干哪行)

    彭博社今日消息,知名芯片制造商 Broadcom 公司正在就收购网络安全公司 Symantec 事宜进行高级会谈,因为 Broadcom 希望寻找半导体业务之外的机会,以实现多元化经营. 据称,在彭博 ...

  8. request.getScheme() 使用方法(转)

    今天在看代码时,发现程序使用了 request.getScheme() .不明白是什么意思,查了一下.结果整理如下: 1.request.getScheme() 返回当前链接使用的协议:一般应用返回h ...

  9. vue添加图片

    首先开始创建一个 static 文件夹用来保存图片 去 setting 里面进行配置 MEDIA_ROOT = os.path.join(BASE_DIR,'media') #前面大写的是死格式,尽量 ...

  10. Spring Boot启动流程分析

    引言 早在15年的时候就开始用spring boot进行开发了,然而一直就只是用用,并没有深入去了解spring boot是以什么原理怎样工作的,说来也惭愧.今天让我们从spring boot启动开始 ...