码迷,mamicode.com
首页 > 其他好文 > 详细

Ocean的游戏(前缀和)

时间:2018-08-14 14:50:20      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:problem   space   cstring   false   arch   data   ssi   lld   data-   

题目链接:http://oj.ismdeep.com/contest/Problem?id=1284&pid=1

B: Ocean的游戏

Time Limit: 1 s      Memory Limit: 128 MB     
My Status

Problem Description

给定一个字符串s,保证只包含小写的’o’,’c’,’e’,’a’,’n’。是否存在这样的偏序对<a,b,I,j,k>使得a<b<i<j<k 并且s[a]+s[b]+s[i]+s[j]+s[k]=”ocean”,请输出偏序对的个数。

Input

第一行输入一个整数n(1n105)n(1≤n≤105);

第二行输入一个长度为nn的字符串ss。

Output

输出一个整数(这个数可能十分大,对109+7109+7取模)

Sample Input

15
oooccceeeaaannn

Sample Output

243

Hint

 

Source

Ocean_Star_T

 

解题思路:做题时知道要用前缀和,但是就是不知道怎么用。看了题解才知道,还可以这么灵活运用。

做法是从前线向后遍历一遍,统计每个位置前面‘oc‘的个数,再从后往前遍历一遍,统计每个位置后面‘an‘的个数,如果遇到‘e‘就用该位置前面‘oc’的个数乘以该位置后面‘an‘的个数,加起来就是子序列‘ocean‘的个数了。

附上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
ll n,ans,cnt1,cnt2;
char s[100005];
ll sum1[100005],sum2[100005];

int main()
{
    scanf("%lld",&n);
    memset(sum1,0,sizeof(sum1));
    memset(sum2,0,sizeof(sum2));
    ans=cnt1=cnt2=0;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
    {
        sum1[i]=sum1[i-1];
        if(s[i]==o) cnt1++;
        if(s[i]==c)
            sum1[i]=(sum1[i]+cnt1)%mod;
    }
    //cout<<sum1[n]<<endl;
    for(int i=n;i>=1;i--)
    {
        sum2[i]=sum2[i+1];
        if(s[i]==n) cnt2++;
        if(s[i]==a)
            sum2[i]=(sum2[i]+cnt2)%mod;
        if(s[i]==e)
            ans=(ans+sum1[i]*sum2[i])%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

 

Ocean的游戏(前缀和)

标签:problem   space   cstring   false   arch   data   ssi   lld   data-   

原文地址:https://www.cnblogs.com/zjl192628928/p/9473796.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!