• UPC OJ 一道水题 STL


    Problem C: 字符串游戏

    Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 10  Solved: 3 [Submit][Status][Web Board]

    Description

    说到游戏,大家还是比较喜欢的,但是玩游戏,如果想赢得对方还是得靠思维的,xy比较喜欢字符串,尤其是起始字母等于终止字母这样的字符串(the string's length must exceed one),但是呢,xy有个癖好,喜欢把每个字符重新分配一个值,喜欢的字符给非负数,不喜欢的字符给负数。但是,xy比较喜欢数字0,所以,他决定找到一个字符串中有多少个字串满足起始字母等于终止字母,且除了起始字母和终止字母外其他字母的和为0。但是xy最近比较忙,希望你能帮助他。

    Input

    第一行包含26个整数xi,xi属于[-100000,100000],非别代表着小写字母a,b,c,....,z的值。

    第二行一个只包含小写字母的字符串,长度你自己猜,算了,给你个范围,length between 1 and 100000.

    Output

    输出答案,每个答案占一行。

    Sample Input

    1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 7 1 1 1 8 1 1 1 1 1 1
    xabcab

    Sample Output

    2

    题目分析:

    每种字母的字符串求一遍,预处理前缀和,每次查找到一个位置i,查询前面有多少与sum[i-1]相同的以该子母为结尾的sum[j],用mp实现,总复杂度O(nlogn)
    刚开始用了multiset中的count函数,总是超时,最后据我推断,那是因为count函数的时间复杂度是O(klogn),k是相同的个数,唉,还是太年轻。
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<string>
    #include<iostream>
    #include<cstdlib>
    #include<queue>
    #include<map>
    using namespace std;
    typedef long long LL;
    char s[100005];
    LL a[26],sum[100005];
    map<LL,int>mp;
    vector<int>b[26];
    int main()
    {
        for(int i=0; i<26; ++i)
            scanf("%lld",&a[i]);
        scanf("%s",s+1);
        int len=strlen(s+1);
        sum[0]=0;
        long long ans=0;
        for(int i=1; i<=len; ++i)
        {
            int c=s[i]-'a';
            sum[i]=sum[i-1]+a[c];
            b[c].push_back(i);
        }
        for(int i=0; i<26; ++i)
        {
            mp.clear();
            for(int j=0; j<b[i].size(); ++j)
            {
                if(j>0)ans+=mp[sum[b[i][j]-1]];
                mp[sum[b[i][j]]]++;
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
     
     
     
    /**************************************************************
        Problem: 3285
        User: 1407010221
        Language: C++
        Result: Accepted
        Time:204 ms
        Memory:2956 kb
    ****************************************************************/
    View Code
    
    
    
    
    
  • 相关阅读:
    用归并排序或树状数组求逆序对数量 poj2299
    UVA10600 次小生成树
    最小生成树求最大比率 UVALive
    求树的重心 poj 1655
    求树的直径+并查集(bfs,dfs都可以)hdu4514
    树形DP+RMQ+尺取法 hdu4123
    区间dp 51nod1021
    LCS poj1080
    最长公共子序列hdu1503
    python No handlers could be found for logger错误的解决
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5023735.html
Copyright © 2020-2023  润新知