codeforces 1291D Irreducible Anagrams 思维

https://vjudge.net/problem/CodeForces-1291D
在这里插入图片描述
在这里插入图片描述题目大意:对于字符串 t t s s ,在两者是相同字母异序词(就是每个字母的出现次数都一样)的基础上,如果说 t t s s 的一个可约序列,那么存在一个 k > = 2 k>=2 使得:
在这里插入图片描述简单来说就是把 t t s s 按顺序划分为 k k 个字串, t i t_i s i s_i 也是相同字母异序词,如果不存在这样的 k k ,那么就说 t t s s 不可约。题目给定了一个字符串 s s ,然后有 n n 个询问 ( l , r ) (l,r) ,表示字符串 s s 的子串 s [ l r ] s[l……r] ,如果能找到一个字符串 t t 使得 t t s s 不可约,输出 Y e s Yes ,否则输出 N o No

思路:这题其实就题目很绕,读懂了还是很好做的,尤其是不可约的情况很容易构造出来。我们考虑一个长度为 l e n len 的字符串 s s ,如果 s [ 1 ] ! = s [ l e n ] s[1]!=s[len] ,那么我们可以构造出一个字符串 t t 使得 t [ 1 ] = s [ l e n ] , t [ l e n ] = s [ 1 ] , t [ 2 l e n 1 ] = s [ 2 l e n 1 ] t[1]=s[len],t[len]=s[1],t[2……len-1]=s[2 ……len-1] ,显然 t t s s 就不可约,因为对于任意 k k t 1 s 1 t_1、s_1 t k s k t_k、s_k 都不是相同字母异序词。考虑 s [ 1 ] = s [ l e n ] s[1]=s[len] 时,如果在 s [ 2 l e n ] s[2……len] 中存在两个和 s [ 1 ] s[1] 不同的字母,我们就可以用第一种情况中的方法构造出一个字符串 t t 使得 t t s s 不可约。那么目前仅存的问题就是如何快速的求出 [ l , r ] [l,r] 内某个元素是否出现过,线段树? N o No ,前缀和就 o k ok 了。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

const int maxn=2e5+5;

int n;
int cnt[26][maxn];
char s[maxn];

int main()
{
    scanf("%s",s+1);
    scanf("%d",&n);
    int l,r,len=strlen(s+1);
    for(int i=1;i<=len;i++)
    {
        for(int j=0;j<26;j++)
            cnt[j][i]=cnt[j][i-1];
        cnt[s[i]-'a'][i]++;
    }
    while(n--)
    {
        scanf("%d%d",&l,&r);
        if(l==r)
            printf("Yes\n");
        else
        {
            if(s[l]!=s[r])
                printf("Yes\n");
            else
            {
                int ct=0;
                for(int i=0;i<26;i++)
                    if('a'+i!=s[l]&&cnt[i][r]-cnt[i][l-1])
                        ++ct;
                if(ct>=2)
                    printf("Yes\n");
                else
                    printf("No\n");
            }
        }
    }
    return 0;
}

发布了677 篇原创文章 · 获赞 30 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/xiji333/article/details/104223964