Red Red Red - 双指针

Red Red Red!!!

题目背景

Red(Yes); Purple(No).

题目描述

小红拿到了一个长度为 n 的字符串,该字符串仅由大写字母组成。
她想取一个子串,该子串包含至少 a 个 'R' 字符,至多 b 个 'P' 字符。
你能告诉她有多少合法的方案可以取到吗?


注意:
1.子串定义见 英文wiki-substring 或 中文wiki-子串
例如:"an" 是 "ant" 的子串而 "at" 不是。
2.只要子串的起始位置或终止位置不同,我们就认为是两个不同的方案。

输入格式

第一行三个正整数 n, a 和 b ,用空格隔开。
第二行一行字符串,该字符串保证仅包含大写字母('A'到'Z')。
数据范围:

 

输出格式

取一个子串,包含至少 a 个 'R' 字符,至多 b 个 'P' 字符的方案数。

输入输出样例

输入 #1

13 3 0
RRRPBRRRDBRPR

输出 #1

10

输入 #2

5 1 1
RARPR

输出 #2

13

 

说明/提示

样例一解释:
共有 10 个合法的子串选择方式。假设下标是从 0 到 12 ,那么 10 个合法串分别是:
s[0,2] = "RRR"
s[4,7] = "BRRR"
s[4,8] = "BRRRD"
s[4,9] = "BRRRDB"
s[4,10] = "BRRRDBR"
s[5,7] = "RRR"
s[5,8] = "RRRD"
s[5,9] = "RRRDB"
s[5,10] = "RRRDBR"
s[6,10] = "RRDBR"
这些串均含有至少 3 个字符 'R',且含有至多 0 个字符 'P'


题解:预处理前缀和,双指针,第二个指针动的时候要二分(可以直接upper_bound)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mo = 1e3;
ll ans = 0;
string s;
int cntr = 0, cntp = 0;
int n, a, b, rr[2000200], pp[2000200];
int main()
{
	ios::sync_with_stdio(false);

	cin >> n >> a >> b;
	cin >> s;
	for (int i = 0; i < n; i++)
	{
		if (s[i] == 'R')
		{
			cntr++;
		}
		rr[i + 1] = cntr;
		if (s[i] == 'P')
		{
			cntp++;
		}
		pp[i + 1] = cntp;
	}
	int j = 1;
	for (int i = 1; i <= n; i++)
	{
		while (rr[j] - rr[i - 1] < a && j < n )
		{
			j++;
		}
		int flg = j;
	//	cout<<"ij= "<<i<<" "<<j<<endl; 
		if (rr[j] - rr[i - 1] >= a)
		{
			int k = upper_bound(pp + 1, pp + n+1, pp[i - 1] + b) - pp-1; //j的位置
		//	cout<<"k= "<<k<<endl;
			if (k > n)k = n;
			int an = k - flg + 1;
			an=max(an,0);
			ans+=an;
			/*   这样做会超时,所以要二分(upper_bound)一下
			while (pp[j] - pp[i - 1] <= b && j <= n)
			{
				ans++;
				j++;
			}*/
		}
		j = max(flg, i + 1);
	}
	cout << ans;
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值