题目来源:click
问一个字符串的子串能不能拆成一个不属于上述情况的字符串。
首先慢慢来分析题目:
其实就是我们一定要让它至少重构成一个无相同前缀的字符串。
1.当l==r的时候根本拆不了两个肯定是Yes。
2.如果只有一种字符串的话显然是No。(这里排除了l=r的情况)
再进一步思考:s与t ,开头与结尾定不能相同,一旦相同其他的字符自成一段。
可以看到,比如在s[i]它是在t中从头往后找一个与之相同的与之对应且之前没配对过。从s[0]开始,t中与s[0]相同的应该尽量放后边,这样才能交织乱也就不能s与t配对,一条纵贯许多的线到t中的终点,之间应该需要有线出去这样可以保证。
3.从上可以知道,当只有两种字符串的时候头尾相同一定是No。
4.当有三种或以上时必可以。
#include <bits/stdc++.h>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
char s[200100];
int dp[200100][26]={0};
int main()
{
s[0]='a';
scanf("%s",s+1);
int len=strlen(s);
len--;
for(int i=1;i<=len;i++)
{
for(int j=0;j<26;j++)
dp[i][j]=dp[i-1][j];
dp[i][s[i]-'a']++;
}
int q;
cin>>q;
while(q--)
{
int l,r;
scanf("%d %d",&l,&r);
if(l==r)
{
printf("Yes\n");
continue;
}
int cnt=0;
for(int i=0;i<26;i++)
{
if(dp[r][i]-dp[l-1][i]>0)
cnt++;
}
if(cnt==1||(s[l]==s[r]&&cnt==2))
{
printf("No\n");
continue;
}
{
printf("Yes\n");
continue;
}
}
return 0;
}