zoukankan      html  css  js  c++  java
  • String

    Problem Description
    You hava a non-empty string which consists of lowercase English letters and may contain at most one '?'. Let's choose non-empty substring G from S (it can be G = S). A substring of a string is a continuous subsequence of the string. if G contains '?' then '?' can be deleted or replaced by one of lowercase english letters. After that if each letter occurs even number of times in G then G is a good substring. Find number of all good substrings.
     
    Input
    The input consists of an integer T, followed by T lines, each containing a non-empty string. The length of the string doesn't exceed 20000.

    [Technical Specification]
    1 <= T <= 100
     
    Output
    For each test case, print a single integer which is the number of good substrings of a given string.
     
    Sample Input
    3 abc?ca aabbcc aaaaa
     
    Sample Output
    7 6 6
     
    题解:用二进制模拟前缀的奇偶状态,如果一个状态x经过添加了几个字母后回到状态x,那么这几个字母肯定符合good substrings。
    感受:又get到了一个新技能。同时深深佩服想出这种方法的大佬。代码有参考网上的博客,不过花了1800多秒,手动实现的map只需要300多秒。
     1 #pragma warning(disable:4996)
     2 #include<map>
     3 #include<string>
     4 #include<cstdio>
     5 #include<bitset>
     6 #include<cstring>
     7 #include<iostream>
     8 #include<algorithm>
     9 using namespace std;
    10 typedef long long ll;
    11 
    12 const int maxn = 2e4 + 4;
    13 
    14 int T;
    15 char s[maxn];
    16 
    17 int main()
    18 {
    19     scanf("%d", &T); while (T--) {
    20         map<int, int> p;
    21         scanf("%s", s);
    22         int pos = -1, n = strlen(s);
    23         for (int i = 0; i < n; i++) if (s[i] == '?') { pos = i; break; }
    24 
    25         int ans = 0, x;
    26         if (pos == -1) {
    27             x = 0; p[0]++;
    28             for (int i = 0; i < n; i++) {
    29                 x ^= 1 << (s[i] - 'a');
    30                 ans += p[x];
    31                 p[x]++;
    32             }
    33             printf("%d
    ", ans);
    34         }
    35         else {
    36             x = 0; p[0]++;
    37             for (int i = 0; i <= pos - 1; i++) {
    38                 x ^= 1 << (s[i] - 'a');
    39                 ans += p[x];
    40                 p[x]++;
    41             }
    42             p.clear();
    43 
    44             x = 0; p[0]++;
    45             for (int i = pos + 1; i < n; i++) {
    46                 x ^= 1 << (s[i] - 'a');
    47                 ans += p[x];
    48                 p[x]++;
    49             }
    50 
    51             x = 0;
    52             if (p.count(x)) ans += p[x];
    53             
    54             for (int i = 0; i < 26; i++) if (p.count(x ^ (1 << i))) ans += p[x ^ (1 << i)];
    55 
    56             for (int i = pos - 1; i >= 0; i--) {
    57                 x ^= 1 << (s[i] - 'a');
    58                 if (p.count(x)) ans += p[x];
    59                 for (int j = 0; j < 26; j++) if (p.count(x ^ (1 << j))) ans += p[x ^ (1 << j)];
    60             }
    61             printf("%d
    ", ans);
    62         }
    63     }
    64     return 0;
    65 }

    网上大佬手动实现的map,值得学习!!!!!!!!!!!!!

     1 #pragma warning(disable:4996)
     2 #include<map>
     3 #include<string>
     4 #include<cstdio>
     5 #include<bitset>
     6 #include<cstring>
     7 #include<iostream>
     8 #include<algorithm>
     9 using namespace std;
    10 typedef long long ll;
    11 
    12 const int maxn = 2e4 + 4;
    13 
    14 char s[maxn];
    15 
    16 struct m_map {
    17     int tot, k[maxn], va[maxn];
    18     int head[maxn], next[maxn];
    19     m_map() { tot = 0; }
    20     void clear() {
    21         tot = 0;
    22         memset(head, -1, sizeof(head));
    23     }
    24     int &get(int v) {
    25         int u = v % maxn;
    26         for (int i = head[u]; i != -1; i = next[i]) if (k[i] == v) return va[i];
    27         k[tot] = v; va[tot] = 0;
    28         next[tot] = head[u];
    29         head[u] = tot;
    30         return va[tot++];
    31     }
    32     int get2(int v) {
    33         int u = v % maxn;
    34         for (int i = head[u]; i != -1; i = next[i]) if (k[i] == v) return va[i];
    35         return 0;
    36     }
    37 }mp;
    38 
    39 int Find(int p, int n) {
    40     mp.clear();
    41     mp.get(0)++;  //初始状态为0,想想"aa"这样的序列
    42     int ans = 0, x = 0;
    43     for (int i = p; i < n; i++) {
    44         x ^= 1 << (s[i] - 'a');
    45         ans += mp.get2(x);
    46         mp.get(x)++;
    47     }
    48     return ans;
    49 }
    50 
    51 int Find2(int p, int n) {
    52     mp.clear();
    53     mp.get(0)++;                //同理
    54     int x = 0, ans = 0;
    55     for (int i = 0; i < p; i++) {
    56         x ^= 1 << (s[i] - 'a');
    57         mp.get(x)++;
    58     }
    59     ans += mp.get2(x);
    60     for (int i = 0; i < 26; i++) ans += mp.get2(x ^ (1 << i));
    61     for (int i = p + 1; i < n; i++) {
    62         x ^= 1 << (s[i] - 'a');
    63         ans += mp.get2(x);
    64         for (int j = 0; j < 26; j++) ans += mp.get2(x ^ (1 << j));
    65     }
    66     return ans;
    67 }
    68 
    69 int main()
    70 {
    71     int T;
    72     scanf("%d", &T);
    73     while (T--) {
    74         scanf("%s", s);
    75         int p = -1, n = strlen(s);
    76         for (int i = 0; i < n; i++) if (s[i] == '?') p = i;
    77         if (p == -1) printf("%d
    ", Find(0, n));
    78         else printf("%d
    ", Find(0, p) + Find(p + 1, n) + Find2(p, n));
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    SOFA 源码分析 — 自动故障剔除
    Pod——状态和生命周期管理及探针和资源限制
    pause的作用
    k8s-部署策略
    linux-删除一个目录下的所有文件,但保留某个或者多个指定文件
    k8s-gitlab搭建
    git中报unable to auto-detect email address 错误的解决拌办法
    k8s-secret用法
    k8s-traefik默认80端口
    nginx和apache区别
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/8619096.html
Copyright © 2011-2022 走看看