zoukankan      html  css  js  c++  java
  • CF-1291 D

    D. Irreducible Anagrams

    题意

    若两个字符串中每个字符的个数都是一样的,则称他们互为(anagrams)。现在定义两个字符串s,t是(reducible~anagram)的,必须满足下面的条件:

    1. 将s、t两个字符串分别拆成k(k>=2)个连续子串
    2. (s_1,s_2cdots s_k) 按顺序排列构成s
    3. (t_1,t_2cdots t_k) 按顺序排列构成t
    4. (forall i in [1,k],都有s_i 是 t_i 的anagrams)
      现在给了一个字符串,每次询问它的一个字串是否存在一个(irreducible~anagram)(请注意这些概念必须是以s是t的(anagrams)前提下进行的)

    分析

    对于每个询问的字符串s,是否存在一个字符串t,使得t是s的(irreducible~anagram).分析题目条件可以将问题转换为:在t和s的任意等长前缀中,它们的字符集的个数必须是不同的(也就是确保它们不是(anagrams))

    我们声明满足下面条件的字符串存在(irreducible~anagram)

    1. 长度等于1
    2. 首字符和尾字符不同
    3. 字符串包含至少三种不同的字符

    求证这些条件后,利用前缀和的技巧可以很容易的解决本题。下面试证一下:

    1. 长度等于1,那么就无法找到一个 k(k>=2) ,所以它的(irreducible~anagram)就是它本身
    2. (s[1] eq s[n]) 即首字符和尾字符不同,我们可以尽量靠前的将所有同(s[n])一样的字符写在前面。然后剩下的字符随便放置即可。可以想到对于任意的(kin[1,n-1]),都满足(s[1..k])(t[1..k])的字符集不同。
    3. 字符串包含至少三种不同的字符,并且(s[1] = s[n])。可以找到一个最大的(j)满足(s[j] eq s[n])。可以把所以同(s[j])一样的字符放到最前面,然后紧挨着中间放置所有同(s[n])的字符,因为不同字符个数大于等于3,所以现在最后面肯定还有空位,将剩余的字符随意放置在最后面即可。可以想到构成的这样的一个串,一定满足任意前缀字符集不等。

    到此为止就可以放心做题了,但试图证明一下为何(s[1] = s[n]~~and~~不同字符个数等于2)的情况为何找不到。
    假设字符只有a和b两种,而且(s[1]=s[n]=a),那么我们构造出来的串必须满足任意前缀中(b)的个数,都大于(s)对应前缀中b的个数。那么考虑(s)中最后出现(b)的位置(x),可以想到(s[1..x-1])前缀比(t[1..x-1])少一个(b),而(s[x]=b)得出现使得(t[x])必须再放置一个(b),这样才能满足任意前缀中b得个数都要比s多,但此时已经没有(b)可以放了(因为(s[1..x-1])就已经多放了一个b)所以在(x)这个位置,无法构造。

    const int N = 200010 + 5;
    char s[N];
    int n, sum[N][26], q, l, r, cnt[26];
    int main() {
        scanf("%s", s+1);
        n = strlen(s + 1);
        for (int i = 1; i <= n;i++){
            memcpy(sum[i], sum[i - 1], sizeof sum[i]);
            sum[i][s[i] - 'a']++;
        }
        scanf("%d", &q);
        while(q--){
            scanf("%d%d", &l, &r);
            if(r - l == 0){
                puts("YES");
                continue;
            }
            int x = 0;
            for (int i = 0; i < 26;i++){
                cnt[i] = sum[r][i] - sum[l - 1][i];
                if(cnt[i])
                    x++;
            }
            if(s[l] == s[r] && x <= 2){
                puts("NO");
            }else
                puts("YES");
        }
        return 0;
    }
    
  • 相关阅读:
    PowerDesigner 15 之Check Model报错信息详解
    js出现:类不支持Automation操作
    IIS错误解决整理
    JavaScript页面跳转的几种方法
    JavaScript刷新上一级页面
    SQL 截断字符串查询(CharIndex()函数)
    JS 判断CHECKBOX复选框多选及选中项验证
    SQL 分组后返回序号(ROW_NUMBER () OVER(PARTITION BY order_no ORDER BY START_Time ASC 的使用方法)
    jquery 获取父窗口的元素 父窗口 子窗口[资料来源于网络]
    SQL Case When Then Else End的使用收集
  • 原文地址:https://www.cnblogs.com/1625--H/p/12254833.html
Copyright © 2011-2022 走看看