P7478 【A】 StickSuger 题解

\(\text{Preface}\)

一个和各位大佬不太一样的做法。

可能更好的体验

\(\text{Description}\)

给定一长度为 \(n\) 的字符串 \(s\),求最大的二元组 \((i,j)\) 满足 \(s_i < s_j\)

定义二元组 \((x_1,y_1) < (x_2,y_2)\) 的概念为:

\[x_1 < x_2 \lor (x_1 = x_2,y_1 < y_2) \]

限制

\(1\le n \le 10^6\)

\(\text{Solution}\)

这个思想非常的暴力:对于每一个字符 \(ch\),我们在 \(ch\) 的前面寻找第一个比其小的字符,统计答案即可。

如何比较快速的寻找一个字符前比其小的第一个字符?

我们可以记录一个 \(A\) 数组,其中 \(A_i\) 表示字符 i+'a' 最后一次出现的位置,每次枚举 \(A\) 数组即可。

时间复杂度:\(\Theta (n)\) (有一个 \(26\) 的常数)

\(\text{Code}\)

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;
}
posted @ 2021-04-10 00:34  feicheng  阅读(80)  评论(0编辑  收藏  举报