CF101532D Couting Test(暴力模拟)

题面:

Yousef has a string s that is used to build a magical string w by repeating the string s infinitely many times. For example, if s = aabbb , then w = aabbbaabbbaabbbaabbb....

Mohammad always claims that his memory is strong, and that his ability to count is very high, so Yousef decided to hold a test for Mohammad, in order to know the truth of his claims.

Yousef will give Mohammad q queries, such that each query consisting of two integers l and r, and a lowercase English letter c. The answer of each query is how many times the letter c appears between the lth and rth letters in string w.

Mohammad must answer all the queries correctly, in order to proof his claims, but currently he is busy finishing his meal. Can you help Mohammad by answering all queries?

 

Input:

The first line contains an integer T, where T is the number of test cases.

The first line of each test case contains two integers n and q (1 ≤ n ≤ 104) (1 ≤ q ≤ 105), where n is the length of string s, and q is the number of queries.

The second line of each test case contains the string s of length n consisting only of lowercase English letters.

Then q lines follow, each line contains two integers l and r and a lowercase English letter c (1 ≤ l ≤ r ≤ 109), giving the queries.

 

Output:

For each query, print a single line containing how many times the letter c appears between the lth and rth letters in string w.

 

Example:

 

Note:

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.

 

分析:

赛中其实想到了主要做法,就是用一个num数组存下当前位置对应字母已经出现了多少次,然后算1-r的出现次数,减去1-l的出现次数,而且奇怪地在这种我一直很迷的边界容易搞不清楚的问题上只改了一次(l--那个地方)就正确了,信心满满地交上去然后TL,哦豁,想到了要做记录来优化,然后!然后!!我竟然想一共会有多少不同字母啊?会把数组开得太大了吧?然后就没有然后了。

结果直到下午补题看到别人的题解我才意识到我这脑袋到底是怎么长的……26个字母啊摔。

做的时候遇到了一个小问题,就是初位置应该从1而不是0开始,这样处理会方便很多,但是cin>>string和%s的方式都让我对怎么把初位置设到1有点迷……然后突然想到可以("%s", &str[1]),顺利解决。

加了记录优化之后竟然还是TL,我就很迷了……改了一些循环的小地方,竟然就AC了,真让人摸不着头脑.jpg

 

AC代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 10010;
int t, n, q;
long long l, r, s, e, ans;
char ch, str[maxn];
int num[26][maxn];

int main(){
	cin>>t;
	while(t--){
		cin>>n>>q;
		scanf("%s", &str[1]);
		for(int i = 0; i < 26; i++){
			int temp = 0;
			for(int j = 0; j <= n; j++){
				if(str[j] - 'a' == i) temp++;
				num[i][j] = temp;
				}
		}
			
		while(q--){
			scanf("%lld %lld %c", &l, &r, &ch);
			ans = 0;
			e = s = 0;
			l--;
			
			s = (l / n) * num[ch - 'a'][n] + num[ch - 'a'][l % n];
			e = (r / n) * num[ch - 'a'][n] + num[ch - 'a'][r % n];
			
			ans = e - s;
			printf("%lld\n", ans);
		}
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值