2666.勇闯黄金十二宫射手宫

原题链接

外网进不去

题目大意

有两串 n ( 1 ≤ n ≤ 100000 ) n(1\le n\le 100000) n(1n100000)个数字的串(每个数都 ≤ 100000 \le 100000 100000),要求求出两个串的最长公共子串的长度。

解题思路

这题,如果使用最长公共子串的方法,时间复杂度将会达到 O ( n 2 ) O(n^2) O(n2),也就是 O ( 10000000000 ) O(10000000000) O(10000000000),所以很明显,这题要换一种做法。深入思考后,会发现这题可以转换为最长不下降子序列来做。我们可以将数字的大小重新定义,将大小关系定义为第二个序列的下标大小。如,在“ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 10,9,8,7,6,5,4,3,2,1 10,9,8,7,6,5,4,3,2,1”和“ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 10,9,8,7,6,5,4,3,2,1 10,9,8,7,6,5,4,3,2,1”中, 10 < 9 < 8 < 7 < 6 < 5 < 4 < 3 < 2 < 1 10<9<8<7<6<5<4<3<2<1 10<9<8<7<6<5<4<3<2<1。使用第二个串的大小关系,对第一个串进行最长不下降子序列来处理,得到的子串长度,就是最长公共子串的长度。但这时,稍加计算会发现,这种做法的时间复杂度将会也达到 O ( n 2 ) O(n^2) O(n2)。怎么优化呢?我们可以使用贪心,如果可以,我们就把它放在结尾,如果不行,就在队列里找到一个位置,是比它小的最大数(尽量大,这样就可以让队列尽量长),并把它替换。
如:
10 , 1 , 2 , 3 , 9 , 8 , 7 , 6 , 5 , 4 10,1,2,3,9,8,7,6,5,4 10123987654
10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 10,9,8,7,6,5,4,3,2,1 10987654321
将第一个序列中的10放入队列中,由于数列是空的,所以直接放在末尾,并把长度加一(10);
将第一个序列中的1放入队列中,由于数列的末尾的下标比1小,所以直接放在末尾,并把长度加一(10,1);
将第一个序列中的2放入队列中,但数列的末尾的下标比2大,我们需要从数量中找到比它小的最大的数,并把它替换掉(长度不用加)(10,2);
将第一个序列中的3放入队列中,但数列的末尾的下标比3大,我们需要从数量中找到比它小的最大的数,并把它替换掉(长度不用加)(10,3);
将第一个序列中的9放入队列中,但数列的末尾的下标比9大,我们需要从数量中找到比它小的最大的数,并把它替换掉(长度不用加)(10,9);
将第一个序列中的8放入队列中,由于数列的末尾的下标比8小,所以直接放在末尾,并把长度加一(10,9,8);
将第一个序列中的7放入队列中,由于数列的末尾的下标比7小,所以直接放在末尾,并把长度加一(10,9,8,7);
将第一个序列中的6放入队列中,由于数列的末尾的下标比6小,所以直接放在末尾,并把长度加一(10,9,8,7,6);
将第一个序列中的5放入队列中,由于数列的末尾的下标比5小,所以直接放在末尾,并把长度加一(10,9,8,7,6,5);
所以,最长公共子串的长度为6(注意:那个队列的长度是最长公共子串的长度,但那个队列不是最长公共子串!),如果用上二分,那时间复杂度将会变成 O ( n ∗ l o g n ) O(n*logn) O(nlogn);

代码实现

#include<iostream>
#include<fstream>
#include<cstdio> 
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<ctime>
#include<set>
#include<ios>
using namespace std;
long long b[200000],x,c[200000],s[200000],n,ans;
int serch(long long x)//二分查找
{
	int l=1,r=ans;
	while(l<r){
		int mid=(l+r)/2;
		if(s[c[mid]]>s[x])
			r=mid;
		else
			l=mid+1;//往大找
	}
	return l;
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>b[i];
	for(int i=1;i<=n;i++){
		cin>>x;
		s[x]=i;
	}//大小定义数组
	for(int i=1;i<=n;i++){
		if(s[b[i]]>s[c[ans]])
			c[++ans]=b[i];//可以放在末尾,直接放
		else
			c[serch(b[i])]=b[i];//不能,使用二分
	}
	cout<<ans;
}

样例

输入

7
1 2 3 4 5 6 7
7 6 5 4 1 2 3

输出

3

### 回答1: 易排盘.紫微斗数v3.0是一款专业的紫微斗数软件。它结合了易学和星法两种传统的中国文化,并利用先进的计算机技术,提供了准确的命盘排算和预测功能。 易排盘.紫微斗数v3.0的主要功能包括命盘排盘、命分析、位解读、十二宫运势、星座配对等。通过输入个人的出生日期、时间和地点,软件可以准确计算出个人的命盘,并提供详细的解读和预测。 命分析是易排盘.紫微斗数v3.0的重要功能之一。通过分析命的星位、星君和星座等信息,软件可以揭示个人的性格特点、运势走向和吉凶指数。它可以帮助人们更好地了解自己的优点和不足,并为未来的发展提供一些建议和方向。 位解读是易排盘.紫微斗数v3.0的另一个关键功能。它通过分析各个位的星座和星位,帮助人们了解自己在事业、爱情、财运和健康等方面的潜力和可能性。位解读可以为人们选择适合自己的发展方向和战略提供重要参考。 十二宫运势是易排盘.紫微斗数v3.0的预测功能之一。通过分析时空的变化和个人命盘的关系,软件可以预测每个人在不同时期的运势走向和吉凶指数。十二宫运势可以帮助人们更好地把握时机、规划未来,以求顺利和成功。 总之,易排盘.紫微斗数v3.0是一款功能强大的紫微斗数软件。它不仅可以帮助人们了解自己的命运和潜力,还可以为个人的发展和决策提供重要参考。无论是对于易学爱好者还是寻求个人发展的人来说,这是一款非常实用和有价值的工具。 ### 回答2: 易排盘是一款专业的紫微斗数软件,它的版本号是v3.0。紫微斗数是一种古老的中国命理学术,通过排盘来分析一个人的命运和命理特点。 易排盘.紫微斗数v3.0具有多种功能和特点。首先,它提供了准确的星盘计算功能,可以根据出生时间、日期和地点准确排盘,得到一个人的生辰八字和命。 其次,它提供了多种分析工具,可以根据紫微斗数的理论,分析一个人的八字命盘,解读其中的吉凶祸福,预测一个人的命运走势。 此外,易排盘.紫微斗数v3.0还提供了丰富的学习资料和案例分析,帮助用户更好地了解紫微斗数的基本原理和应用方法。 另外,易排盘.紫微斗数v3.0还提供了个性化的设置功能,用户可以根据自己的需求进行设置,例如选择特定的历法和计算方式等。 总的来说,易排盘.紫微斗数v3.0是一款功能强大、专业准确的紫微斗数软件,它通过准确的星盘计算和丰富的分析工具,帮助用户深入研究命理学术,解读命运,做出更好的决策。具体来说,用户可以通过它来了解自己的八字命盘,预测个人运势,以及选择合适的发展方向。 ### 回答3: 易排盘.紫微斗数v3.0是一款专业的紫微斗数软件,主要用于命理推断和占卜。它结合了易经和紫微斗数理论,并借助计算机算法,提供准确、快速的命运分析和预测。 该软件首先需要用户提供出生日期、出生地点和出生时间等信息,然后根据紫微斗数的理论将这些信息转化为对应的命盘图。命盘图由十二宫位和星宿组成,每个位代表不同的人生领域,而星曜则代表个人的命运和特质。 软件会根据用户的命盘图分析个人的性格特点、事业发展、财富状况、婚姻情况、健康状况等方面的信息。通过分析十二宫位和星曜的位置和相互关系,软件能够准确预测用户的人生走势和重要事件,并给出相应的建议和指导。 这个软件的优势在于它的准确性和全面性。它使用复杂的算法和紫微斗数的理论,能够在短时间内为用户做出系统全面的命运分析。它的计算速度快,准确性高,不会受到人的主观意识和偏见影响。 此外,易排盘.紫微斗数v3.0还提供了易经占卜的功能。用户可以根据自己的问题,输入相关信息,软件会根据易经的原理和卦象的图像,为用户提供具体的占卜结果和解答。 总之,易排盘.紫微斗数v3.0是一款功能强大、准确可靠的紫微斗数软件。它能够帮助用户了解自己的命运走势,为个人的发展提供指导和建议。无论是对于命理学研究者还是对于对自己命运感兴趣的人来说,这是一款值得拥有的优秀软件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值