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
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(1≤n≤105)n(1≤n≤105);
第二行输入一个长度为nn的字符串ss。
Output
输出一个整数(这个数可能十分大,对109+7109+7取模)
Sample Input
15
oooccceeeaaannn
Sample Output
243
Hint
Source
解题思路:做题时知道要用前缀和,但是就是不知道怎么用。看了题解才知道,还可以这么灵活运用。
做法是从前线向后遍历一遍,统计每个位置前面‘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 配置文件?