首页 > 其他分享 >[ABC354F] Useless for LIS

[ABC354F] Useless for LIS

时间:2024-06-07 22:44:42浏览次数:26  
标签:10 cnt leq int ABC354F Useless LIS 序列 最長

写在最前面的话:如果你懂这道题的线段树或者树状数组解法,那么本题解对你可能没有帮助。

题目传送门(Luogu)
题目传送门(AtCoder)

[ABC354F] Useless for LIS

题面翻译

  • 给定一个长度为 \(n\) 的序列 \(a\)。求出所有 \(i\) 使得存在任意一个 \(a\) 的最长上升子序列包含 \(i\)。多测。
  • \(1 \le T, n, \sum n \le 2 \times 10^5\),\(1 \le a_i \le 10^9\)。

题目描述

長さ $ N $ の整数列 $ A $ が与えられます。

$ t\ =\ 1,\ 2,\ \dots\ ,N $ について、 $ A_t $ が $ A $ の最長増加部分列に含まれることがあるか判定してください。

$ A_t $ が $ A $ の最長増加部分列に含まれることがあるとは、以下のことをいいます。

  • 最長増加部分列の長さを $ L $ とする。各要素が $ 1 $ 以上 $ N $ 以下の単調増加な整数列 $ i\ =\ (i_1,\ i_2,\ \dots\ ,i_L)\ (i_1\ であって以下をすべて満たすものが存在する。 $

    • $ A_{i_1} $
    • ある $ k\ (1\ \leq\ k\ \leq\ L) $ が存在して $ i_k\ =\ t $ である

$ T $ 個のテストケースが与えられるので、それぞれについて答えを求めてください。

最長増加部分列とは?列 $ A $ の部分列とは $ A $ の要素をいくつか抜き出して元の順に並べてできる列を指します。

列 $ A $ の最長増加部分列とは、 $ A $ の狭義単調増加な部分列のうち列の長さが最大のものを指します。

输入格式

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

$ T $ $ \mathrm{case}_1 $ $ \mathrm{case}_2 $ $ \vdots $ $ \mathrm{case}_T $

ここで $ \mathrm{case_i} $ は $ i $ 番目のケースの入力を意味する。各ケースは以下の形式で与えられる。

$ N $ $ A_1 $ $ A_2 $ $ \cdots $ $ A_N $

输出格式

以下の形式で出力せよ。

\(\mathrm{answer}_1\) \(\mathrm{answer}_2\) \(\vdots\) \(\mathrm{answer}_T\)

ここで $ \mathrm{answer}_i $ は $ i $ 番目のケースの出力を意味する。各ケースについては、次の通りである。

$ A_t $ が $ A $ の最長増加部分列に含まれることがある $ t $ が $ m $ 個存在し、昇順に $ i_1,\ i_2,\ \dots\ ,i_m $ であったとする。このとき、以下の形式で出力せよ。

$ m $ $ i_1 $ $ i_2 $ $ \cdots $ $ i_m $

样例 #1

样例输入 #1

1
5
2 1 4 5 3

样例输出 #1

4
1 2 3 4

样例 #2

样例输入 #2

2
6
2 5 3 4 3 4
5
10000 1000 100 1 10

样例输出 #2

5
1 3 4 5 6
2
4 5

提示

制約

  • \(1\ \leq\ T\ \leq\ 2\ \times\ 10^5\)
  • \(1\ \leq\ N\ \leq\ 2\ \times\ 10^5\)
  • \(1\ \leq\ A_i\ \leq\ 10^9\)
  • 全てのテストケースにおける \(N\) の総和は \(2\ \times\ 10^5\) 以下

Sample Explanation 1

最長増加部分列の $ 1 $ つは $ (2,\ 4,\ 5) $ で、長さは $ 3 $ です。$ (1,\ 4,\ 5) $ も最長増加部分列の $ 1 $ つです。しかし、 $ A_5 $ を含む最長増加部分列はありません。 よって、 $ 1,\ 2,\ 3,\ 4 $ を出力します。

题目解析

给你一个长度为 \(N\) 的序列,问你那些元素有可能出现在最长上升子序列中。\(N \leq 2 \times 10^{5}\)。

首先,一个个枚举最长上生子序列然后记录肯定不行(可以用搜索做,但 \(N\) 很大,试问 \(2^{2 \times 10^{5}}\) 会不会TLE),而且第一反应应该是动态规划,而且是二分优化的动态规划(\(N \log N\) 不会超)。可以枚举每个 \(a_i\),然后看看 \(a_i\) 能不能和其他元素一起构成一个长度等于原序列最长上生子序列长度的子序列,这个包含 \(a_i\) 的自序列就可以拆成两部分算:\(a_i\) 和小于 \(a_i\)的,\(a_i\) 和大于 \(a_i\) 的(\(a_i\) 算了两次,算的时候要减一),也就是以 \(a_i\) 结尾的和以 \(a_i\) 开头的。把它们的长度加起来减去一,如果等于原序列最长上生子序列的长度,\(i\) 就是答案之一。

以 \(a_i\) 结尾的最长上升自序列的长度好算,那么以 \(a_i\) 开头的最长上生子序列怎么算呢?把 \(a\) 序列倒过来(相当于reverse),然后给每个元素取反(乘以负一),对新得到的序列(暂且称其为 \(b\))求以 \(b_i\) 结尾的最长上升自序列,那么 \(a_i\) 开头的最长上升自序列的长度就等于以 \(b_{n-i+1}\) 结尾的最长上升自序列。

AC code(请不要介意我奇怪的码风):

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int T,n,a[N],f[N],dp[N],cnt,b[N],f2[N],dp2[N],cnt2;
int main(){
	//freopen("xx.in","r",stdin);
	//freopen("xx.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>T;
	while(T--){
		cnt=0;
		cnt2=0;
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		for(int i=1;i<=n;i++){
			if(a[i]>f[cnt]){
				f[++cnt]=a[i];
				dp[i]=cnt;
			}else{
				int x=lower_bound(f+1,f+cnt+1,a[i])-f;
				x=min(x,cnt);
				dp[i]=x;
				f[x]=a[i];
			}
		}
		for(int i=1;i<=n;i++){
			b[i]=a[n-i+1];
			b[i]=-b[i];
		}
		f2[0]=INT_MIN;
		for(int i=1;i<=n;i++){
			if(b[i]>f2[cnt2]){
				f2[++cnt2]=b[i];
				dp2[i]=cnt2;
			}else{
				int x=lower_bound(f2+1,f2+cnt2+1,b[i])-f2;
				x=min(x,cnt);
				dp2[i]=x;
				f2[x]=b[i];
			}
		}
		int maxs=0;
		for(int i=1;i<=n;i++){
			maxs=max(maxs,dp[i]);
		}
		int cnt=0;
		for(int i=1;i<=n;i++){
			if(dp[i]+dp2[n-i+1]-1==maxs){
				cnt++;
			}
		}
		cout<<cnt<<"\n";
		for(int i=1;i<=n;i++){
			if(dp[i]+dp2[n-i+1]-1==maxs){
				cout<<i<<" ";
			}
		}
		cout<<"\n";
	}
	return 0;
}

附:人生第一次 Unknown Error,所以在AtCoder上交的

完结撒花!

标签:10,cnt,leq,int,ABC354F,Useless,LIS,序列,最長
From: https://www.cnblogs.com/wuyiming1263/p/18237982

相关文章

  • C++STL---list模拟实现
    本文我们模拟实现STL中的list,为了模拟实现list,实际上我们需要实现三个类,分别为:_list_node,_list_iterator,list。我们先看一下这三个类的基本组成,主要是看看每个类中包含的变量有什么:namespaceCYF{ //模拟实现list当中的结点类 template<classT> struct_list_node......
  • list 列表(属于集合collection中的一种)
    list类型,有序可变list内的数据可以混合,string+int等 取出集合内元素:list=["hello",11,33,"world"](index索引从0开始)0123单个取出:(变量接收)=list[0]批量取出:(变量接收)=list[0:2](此处范围包左不包右,去除的元素索引为0和1) 内置函数:(变......
  • 【C++进阶】深入STL之list:高效双向链表的使用技巧
    ......
  • Android Adapter中组件EditText文本变化监听 addTextChangedListener
    问题背景:使用适配器显示一个列表,列表中Item中有EditText,滚动时会有EditText组件内容消失步骤:1.在Adapter中,添加interfacepublicinterfaceOnEidtTextChangeListener{ voidxxxTextChanged(CharSequences,intstart,intbefore,intcount); voidgetXxxEditedCount(......
  • Android 水平滚动List 一项Item占满一页宽 设定单次滑动一次切换一次Item
    背景:水平滚动的List,一项Item占满页面宽度,相当于数量不定的选项卡,每个选项卡占满一页,左右滑动时,如何限制一次只能滑动一个Item步骤:1.水平滚动布局linearLayoutManager=newLinearLayoutManager(this);linearLayoutManager.setOrientation(LinearLayoutMana......
  • 基于AnolisOS 8.6的OpenVPN和GmSSLv2国密算法SSL VPN测试
    测试环境AnolisOS-8.6-x86_64-minimal.isoVirtualBox,2vCPU,4GRAM,40vDisk安装依赖yuminstall-ymakegcc编译安装GmSSLunzipGmSSL-master.zip**注:**由于许多系统有自带的ssl库,为避免潜在的动态库冲突,此处仅生成静态库./config--prefix=/usr/local/gmssl......
  • 【栈】736. Lisp 语法解析
    本文涉及知识点栈LeetCode736.Lisp语法解析给你一个类似Lisp语句的字符串表达式expression,求出其计算结果。表达式语法如下所示:表达式可以为整数,let表达式,add表达式,mult表达式,或赋值的变量。表达式的结果总是一个整数。(整数可以是正整数、负整数、0)let表......
  • mcc mnc list
    mccmnclist来源  https://www.mcc-mnc.com/ MCCMNCISOCountryCountryCodeNetwork28968geAbkhazia7A-Mobile28988geAbkhazia7A-Mobile28967geAbkhazia7Aquafon289299geAbkhazia7FailedCalls289999geAbkhazia7FixLine412......
  • java:数组和集合(例如ArrayList)的对比
    问题:为什么java里有了array还要有arrayList?(相类比的:python里只有list没有array)答案:因为arrayList是对array的补充,更灵活实用。数组和arrayList都是一维的,但数组可以通过下标直接访问,arrayList只能通过遍历访问;数组能存储基本类型和对象,arrayList只能存对象;数组长度不可变,array......
  • AnolisOS7.9(CentOS7)部署K8s(1.22.4)集群
    一.安装K8s集群1.准备工作,2台服务器①192.168.5.140-做为master节点#在该节点运行命令设置主机名:hostnamectlset-hostnamemaster②192.168.5.141-做为node1节点,在该节点运行命令设置主机名:#在该节点运行命令设置主机名:hostnamectlset-hostna......