ABC381D题解

原题

AT_abc381_d [ABC381D] 1122 Substring

题目描述

正整数からなる(空でも良い)数列 $ X=(X_1,X_2,\ldots) $ が以下の $ 3 $ つの条件をすべてみたすとき、かつそのときに限り、$ X $ を 1122 数列 と呼びます。
(1122 数列の定義はF問題と共通です。)

  • $ \lvert\ X\ \rvert $ は偶数である。ここで、$ \lvert\ X\ \rvert $ は $ X $ の長さを表す。
  • $ 1\leq\ i\leq\ \frac{\lvert\ X\ \rvert}{2} $ をみたす整数 $ i $ について、$ X_{2i-1} $ と $ X_{2i} $ は等しい。
  • 各正整数は $ X $ に現れないか、ちょうど $ 2 $ 回現れるかのどちらかである。すなわち、$ X $ に含まれる正整数は $ X $ にちょうど $ 2 $ 回ずつ登場する。

正整数からなる長さ $ N $ の数列 $ A=(A_1,A_2,\ldots,A_N) $ が与えられるので、$ A $ の 連続する部分列 であって、1122 数列であるようなもののうち最長のものの長さを出力してください。

输入格式

入力は以下の形式で標準入力から与えられる。

$ N $ $ A_1 $ $ A_2 $ $ \ldots $ $ A_N $

输出格式

$ A $ の連続する部分列であって、1122 数列であるようなもののうち最長のものの長さを出力せよ。

输入输出样例 #1

输入 #1

8
2 3 1 1 2 2 1 1

输出 #1

4

输入输出样例 #2

输入 #2

3
1 2 2

输出 #2

2

输入输出样例 #3

输入 #3

1
1

输出 #3

0

说明/提示

制約

  • $ 1\leq\ N\ \leq\ 2\times\ 10^5 $
  • $ 1\leq\ A_i\ \leq\ N $
  • 入力はすべて整数

Sample Explanation 1

例えば $ A $ の $ 3 $ 項目から $ 6 $ 項目までの連続部分列をとると $ (1,1,2,2) $ となりますが、これは長さが $ 4 $ の 1122 数列となっています。 これより長い部分列であって、1122 数列の条件をみたすようなものは存在しないため、$ 4 $ を出力します。

Sample Explanation 3

項数が $ 0 $ の列も 1122 数列の条件をみたしていることに注意してください。

思路

可以用一个双指针,和一个桶来记录,记得要从第一个数和第二个数分别开始。

简单版

我们先考虑可以重复,则直接如果检测到第二个指针与下一个不相同,就直接将第一个指针移动这。否则就将第二个指针往后移两步。最后每次操作都将这个长度取最大值。

进阶版

考虑不可以重复,则用一个桶记录每个数上一次出现地方。然后如果第二个指针对应的数上次出现的的地方在这个区间内,则将第一个指针拉到上一次出现的位置。其它步骤与简单版相同。

Code

#include<bits/stdc++.h>
using namespace std;
int n,a[2000005],tong[2000005];
int ans(int top){
	int mx=0;
	memset(tong,0,sizeof(tong));
	for(int l=top,r=top;r<n;){
		if(a[r]!=a[r+1]){
			l=r=r+2;
		}
		else{
			if(tong[a[r]]>=l){
				l=tong[a[r]]+2;
			}
			tong[a[r]]=r,r+=2;
		}
		mx=max(mx,r-l);
	}
	return mx;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	cout<<max(ans(1),ans(2));
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值