1 条题解

  • 0
    @ 2024-12-24 1:26:47

    这是一个字符串统计类题目,一般都需要使用组合数学的思想。

    给定一个字符串,请找出子序列 yxh\text{yxh} 的个数。

    暴力做法:33 重循环依次枚举这三个字符,然后累加,当然时间复杂度不可行。

    考虑优化,之前的暴力是一个一个找的,我们能否一次找多个,比如固定某个位置的 yx\text{yx} 找这个后面的 h\text{h} 出现的次数,这样可行,我们可以预处理一下关于 h\text h 的个数前缀和,这样就优化了一重循环,时间复杂度还是 O(n2)O(n^2)

    还需优化,我们根据上面的思路,我们这一次固定 x\text x 的位置,那么我们就需要知道 x\text x 前面的位置有多少 y\text y,后面有多少 h\text h。所以根据乘法原理我们这一个 x\text x 的贡献就是前 y\text{y} 和后 h\text{h} 的乘积,即预处理前缀和 y\text{y}h\text{h},然后遍历到 x\text x 位置的时候统计一下贡献即可。

    时间复杂度为:O(n)O(n)

    参考代码:

    #include <bits/stdc++.h>
    
    using u32 = unsigned;
    using i64 = long long;
    using u64 = unsigned long long;
    using u128 = unsigned __int128;
    
    int main() {
    	std::ios::sync_with_stdio(false);
    	std::cin.tie(nullptr);
    
    	int n;
    	std::cin >> n;
    	std::string s;
    	std::cin >> s;
    	std::vector<i64> y(n + 1), h(n + 1);
    	for (int i = 1; i <= n; i++) {
    		y[i] = y[i - 1] + (s[i - 1] == 'y');
    		h[i] = h[i - 1] + (s[i - 1] == 'h');
    	}
    
    	i64 ans = 0;
    
    	for (int i = 1; i <= n; i++) {
    		if (s[i - 1] == 'x') {
    			ans += y[i] * (h[n] - h[i]);
    		}
    	}
    	std::cout << ans << "\n";
    
    	return 0;
    }
    
    • 1

    信息

    ID
    151
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    60
    已通过
    13
    上传者