一个和各位大佬不太一样的做法。
给定一长度为 \(n\) 的字符串 \(s\),求最大的二元组 \((i,j)\) 满足 \(s_i < s_j\)
定义二元组 \((x_1,y_1) < (x_2,y_2)\) 的概念为:
限制
\(1\le n \le 10^6\)
这个思想非常的暴力:对于每一个字符 \(ch\),我们在 \(ch\) 的前面寻找第一个比其小的字符,统计答案即可。
如何比较快速的寻找一个字符前比其小的第一个字符?
我们可以记录一个 \(A\) 数组,其中 \(A_i\) 表示字符 i+‘a‘
最后一次出现的位置,每次枚举 \(A\) 数组即可。
时间复杂度:\(\Theta (n)\) (有一个 \(26\) 的常数)
constexpr int N = 1e6 + 10 ;
char s[N] ;
int n,flag;
int A[26] ;
inline int Getpos(const int x) {
int ans = -1;
for(int i = 0;i < x;++i) ans = max(ans,A[i]) ;
return ans ;
}//寻找第一个位置
int main(int argc,const char **argv) {
memset(A,-1,sizeof A) ;
cin >> n >> (s+1) ;
std::pair<int,int> ans ;
for(int i = 1;i <= n;++i) {
A[s[i]-‘a‘] = i ;
const int p = Getpos(s[i]-‘a‘) ;
if(p != -1) flag = 1,ans = std::max(ans,std::make_pair(p,i)) ;
//我们发现对于二元组小于号的定义恰好满足 pair 的定义,就可以用pair来存储答案。
}
if(!flag) cout << -1 ;
else cout << ans.first << " " << ans.second ;
return hl::flush(),0;
}
原文:https://www.cnblogs.com/hl-fc/p/14639369.html