(The 11th Blue Bridge Cup Provincial Competition) Test Question H: Sum of Substring Scores (Thinking) (The example is incorrect)

Topic link: Featured Project Courses_IT Popular Courses_Blue Bridge Cloud Course-Blue Bridge Cloud Course

Analysis: I think this question is still a good question, so come and record it:

First, looking at the data range of n, we know that this problem can only be passed with the complexity of o(n) or o(nlogn). Of course, o(n^2) can also get partial points. I will give the correct solution below. :

It is impossible for us to traverse each substring in S to find its f value, but we can find the contribution of each character in S to the final answer and finally sum the contributions of each letter . Take ababc as an example , let's analyze the contribution of the third character a first. Let's assume that this a contributes 1 to each substring that contains him, then his contribution is 3*3=9, because he is the third from the left of the S sequence is also the third one from the right. We choose a number from the first three positions in S as l, and then choose a number from the last three positions in S as r, then any [l,r] sequence contains This a, but we quickly found that it is wrong to think about the problem this way, because it will repeat the calculation . For example, aba is also a substring of S, but there are two a in this substring. Which a does the contribution belong to? So obviously it can't be calculated as just now, is that the interval l of the contribution interval of our current letter is included in the interval from the first position to the right of the position where the current letter appeared last to the position of the current letter, and the contribution of the current letter is The r of the interval contains the interval from the first position to the left of the next occurrence of the current letter to the position of the current letter. This regulation ensures that each substring we select can only contain each letter once , but We will miss some cases in this way. It is not difficult to find that for aba, our letter a still contributes, but we can never traverse to the substring containing the same letter as we just defined, so defining the contribution in that way will lead to leakage. , in order to consider each substring without fail, we can define the contribution of a letter as follows: the interval l of the contribution of the current letter contains the interval to the current letter one position to the right of the position where the current letter last appeared, and The r of the contribution interval of the current letter is included in the interval from the position of the current letter to the right endpoint of the S string , which ensures that the contribution of the string is counted as the first character every time a repeated letter appears in the selected substring. Contribution of occurrences of letters, so that the contribution of each letter can be calculated without repetition. The special case is that there is no same letter on the left of a certain letter, then we can deal with it according to the left boundary.

Here is the code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
const int N=30;
vector<int>p[N];
int main()
{
	string s;
	cin>>s;
	long long len=s.size();
	s=" "+s;//让下标从1开始 
	for(int i=1;i<=len;i++)
		p[s[i]-'a'+1].push_back(i);
	long long ans=0;
	for(int i=1;i<=len;i++)
	{
		int t=s[i]-'a'+1;
		int last;
		int id=lower_bound(p[t].begin(),p[t].end(),i)-p[t].begin();//求出第i个字母是第几次出现 
		if(id) last=p[t][id-1]+1;
		else last=1;
		ans+=(i-last+1)*(len-last+1);
	}
	cout<<ans;
	return 0;
}

Guess you like

Origin blog.csdn.net/AC__dream/article/details/123972726