zoukankan      html  css  js  c++  java
  • Codeforces Round #294 (Div. 2) D. A and B and Interesting Substrings

    题意:
    对于26个字母 每个字母分别有一个权值
    给出一个字符串,找出有多少个满足条件的子串,
    条件:1、第一个字母和最后一个相同,2、除了第一个和最后一个字母外,其他的权和为0

    思路:
    预处理出sum[i]:s[0~i]的和
    开26个map<LL, LL>numV 分别表示 每个字母前缀和 的个数
    例如处理到第i个元素,且numV[s[i]-'a'][sum[i]-v[s[i] - 'a']] (值为2)
    表示在处理到的元素之前 以s[i]结尾的前缀和为sum[i]-v[s[i]-'a']的个数有2个
    所以答案就要加2(因为前面已经组成过这个值,又出现的原因就是他的值变为了0)

     1 const int maxv = 30;
     2 int v[maxv];
     3 map<LL, LL> numV[maxv];
     4 
     5 const int maxn = 100000 + 10;
     6 char s[maxn];
     7 LL sum[maxn];
     8 void init()
     9 {
    10     for (int i = 0; i < 26; i++)
    11     {
    12         scanf("%d", v + i);
    13     }
    14     scanf(" ");
    15     gets(s);
    16 }
    17 
    18 void solve()
    19 {
    20     int len = strlen(s);
    21     sum[0] = v[s[0]-'a'];
    22     for (int i = 1; i < len; i++)
    23     {
    24         sum[i] = sum[i-1] + v[s[i]-'a'];
    25     }
    26 
    27     LL ans = 0;
    28     for (int i = 0; i < len; i++)
    29     {
    30         ans += numV[s[i]-'a'][sum[i] - v[s[i] - 'a']];
    31         numV[s[i]-'a'][sum[i]]++;
    32     }
    33     printf("%lld
    ", ans);
    34 }
    35 
    36 int main()
    37 {
    38     init();
    39     solve();
    40     return 0;
    41 }
  • 相关阅读:
    1034: [ZJOI2008]泡泡堂BNB
    1084: [SCOI2005]最大子矩阵
    1046: [HAOI2007]上升序列
    LIS最长上升子序列模板
    1070: [SCOI2007]修车
    1057: [ZJOI2007]棋盘制作
    1066: [SCOI2007]蜥蜴
    1059: [ZJOI2007]矩阵游戏
    1050: [HAOI2006]旅行comf
    1083: [SCOI2005]繁忙的都市
  • 原文地址:https://www.cnblogs.com/liangyongrui/p/6065558.html
Copyright © 2011-2022 走看看