CF-1291D. Irreducible Anagrams(构造算法)

总结

题意:构造一个t字符串,满足irreducible anagram ,输出yes,否则输出no
reducible anagram = k*irreducible anagram(k>=2)
满足三个条件某一个即可:

第一:l==r(k>=2,才能构成reducible anagram)

第二:s[l] != s[r]

不同字符是这个题的核心点
这种字符串,可以构造一个把t字符串中与s[r]相同的字符串全部放在t的最左端,其他字符随便放置,你会发现sk要找到tk匹配,那么s1-k跟t1-k一定不匹配,因为这个时候,t1-k全是s[r],但是s1-k中有一个字符s[l]。

第三:cnt>=3

上面已经处理了首尾不同字符的问题,那么首尾相同字符

情况1:字符串不同字符数量为1

显而易见,|s|>=2,没办法构造,t是唯一的,一定是reducible anagram

情况2:字符串不同字符数量为2

s1的所有情况,最特殊的就是就是s1的首尾字符不一样,这种一定可以构成一个irreducible anagram,但是只是s1== t1,剩下的就可以完成s1-k ==t1-k,就满足了k>=2

情况3:字符串不同字符数量为3

直接举例子:s=aabcaa
把c构造在t的最左边,b构造在最右边

c要满足一个那么c所在的区间一定t[1,4], a和c不同
d要满足一个那么d所在的区间一定t[3,6] d和a不同
两个区间一合并,就是只是一个irreducible anagram

情况4:字符串不同字符数量为大于等于4

就把多余的字符串上面字符串aabcaa的bc的中间就可以了

const int N=2e5+5;
int dp[N][26],cnt[26];
signed main()///构造算法
{
    IOS;
    //file();
    string str;
    cin>>str;
    int n=str.size();
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<26;j++)
            dp[i][j]=dp[i-1][j];
        dp[i][str[i-1]-'a']++;
    }
    int q;
    cin>>q;
    while(q--)
    {
        int l,r,sum=0;
        cin>>l>>r;
        for(int i=0;i<26;i++)
            if(dp[r][i]-dp[l-1][i])
                sum++;
        if(r==l||str[l-1]!=str[r-1]||sum>=3)
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
    return 0;
}
发布了130 篇原创文章 · 获赞 5 · 访问量 4997

猜你喜欢

转载自blog.csdn.net/weixin_44224825/article/details/104157509