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 */

  

  

最新文章

  1. HTML动画分类 HTML5动画 SVG库 SVG工具 Canvas动画工具
  2. rsync+inotify实时同步环境部署记录
  3. 一幅图概括Android测试的方方面面
  4. [BZOJ 3774] 最优选择 【最小割】
  5. 转:fopen()函数
  6. POJ 3928 &amp;amp; HDU 2492 Ping pong(树阵评价倒数)
  7. 编译预处理命令define
  8. Vim-latex 插件 的安装
  9. 内存管理中提到的hot cold page
  10. FLASK-----基本知识(一)
  11. 四重解法---P1047 校门外的树
  12. C# 后台请求api
  13. hbase 1.2.1 分布式安装
  14. SSE图像算法优化系列三:超高速导向滤波实现过程纪要(欢迎挑战)
  15. 【译】第11节---数据注解-TimeStamp
  16. vue之v-if和v-show
  17. 25-hadoop-hive-函数
  18. 【noip模拟赛1】古韵之同心锁
  19. 装上了Fedora19
  20. bzoj 3522 tree-dp 暴力

热门文章

  1. Maven仓库介绍以及私服搭建
  2. celery异步任务
  3. select key from table 一直出错
  4. 关于greenlet的一些问题
  5. go语言操作kafka
  6. 编写并提取简易 ShellCode
  7. Linux/CentOS 配置Mysql-server过程和遇到错误解决方法
  8. java中的exception stack有时候不输出的原因
  9. iOS 定义多个参数函数的写法
  10. LeetCode 腾讯精选50题-- 买卖股票的最佳时机 II