codeforce452DIV2——E. Segments Removal

题目

Vasya has an array of integers of length n.

Vasya performs the following operations on the array: on each step he finds the longest segment of consecutive equal integers (the leftmost, if there are several such segments) and removes it. For example, if Vasya's array is [13, 13, 7, 7, 7, 2, 2, 2], then after one operation it becomes [13, 13, 2, 2, 2].

Compute the number of operations Vasya should make until the array becomes empty, i.e. Vasya removes all elements from it.

分析

链表+优先队列

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <queue>
 6 
 7 using namespace std;
 8 const int maxn=200000+10;
 9 int a[maxn];
10 int vis[maxn];
11 
12 struct Node{
13     int len,id,val,l;
14     bool operator <(const Node &rhs)const{
15         return len<rhs.len||(len==rhs.len&&l>rhs.l);
16     }
17 }node[maxn];
18 
19 int n;
20 int Next[maxn],Last[maxn];
21 int main(){
22     memset(vis,0,sizeof(vis));
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++){
25         scanf("%d",&a[i]);
26     }
27    int cnt=0,m=0;
28     for(int i=1;i<=n;i++){
29         cnt++;
30         if(a[i]!=a[i+1]){
31             node[++m].len=cnt;
32             node[m].id=m;
33             node[m].val=a[i];
34             node[m].l=i;
35             cnt=0;
36         }
37     }
38     priority_queue<Node>q;
39     //printf("%d",m);
40 
41     for(int i=1;i<=m;i++){
42         Next[i]=i+1;
43         Last[i]=i-1;
44         q.push(node[i]);
45     }
46     Next[m]=0;Last[1]=0;
47     int ans=0;
48     while(!q.empty()){
49         while(!q.empty()&&vis[q.top().id])q.pop();
50         if(!q.empty()){
51         Node x=q.top();q.pop();
52         //printf("%d :%d %d\n",x.id,Next[x.id],Last[x.id]);
53         //printf("%d %d %d\n",x.id,x.len,x.val);
54         ans++;
55         Next[Last[x.id]]=Next[x.id];
56         Last[Next[x.id]]=Last[x.id];
57         if(Last[x.id]&&Next[x.id]&&node[Last[x.id]].val==node[Next[x.id]].val&&!vis[node[Last[x.id]].id]&&!vis[node[Next[x.id]].id]){
58                 vis[node[Last[x.id]].id]=1;
59                 vis[node[Next[x.id]].id]=1;
60                 
61                 int l=node[Next[x.id]].l;
62                 node[++m].val=node[Last[x.id]].val;
63                 node[m].len=node[Last[x.id]].len+node[Next[x.id]].len;
64                 node[m].id=m;
65                 node[m].l=l;
66                 Next[Last[Last[x.id]]]=m;
67                 Last[Next[Next[x.id]]]=m;
68                 Next[m]=Next[Next[x.id]];
69                 Last[m]=Last[Last[x.id]];
70                 q.push(node[m]);
71         }
72         }
73     }
74    printf("%d",ans);
75 
76 return 0;
77 } 
View Code

 

转载于:https://www.cnblogs.com/LQLlulu/p/8785894.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值