Ocean的游戏(前缀和)

Posted zjl192628928

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ocean的游戏(前缀和)相关的知识,希望对你有一定的参考价值。

题目链接: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
",ans);
    return 0;
}

 

以上是关于Ocean的游戏(前缀和)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Digital Ocean 的源代码控制中包含 nginx 和 gunicorn 配置文件?

[置换 前缀和]牛牛的猜球游戏

从片段调用 Google Play 游戏服务

Ogre的Ocean例子理解

Leetcode5765. 跳跃游戏 VII(前缀和+DP)

微信小程序代码片段