codeforces 509E Pretty Song [递推]【杂类】

题目链接:http://codeforces.com/contest/509/problem/E
—————————————————————————————–.
E. Pretty Song
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
When Sasha was studying in the seventh grade, he started listening to music a lot. In order to evaluate which songs he likes more, he introduced the notion of the song’s prettiness. The title of the song is a word consisting of uppercase Latin letters. The prettiness of the song is the prettiness of its title.

Let’s define the simple prettiness of a word as the ratio of the number of vowels in the word to the number of all letters in the word.

Let’s define the prettiness of a word as the sum of simple prettiness of all the substrings of the word.

More formally, let’s define the function vowel(c) which is equal to 1, if c is a vowel, and to 0 otherwise. Let si be the i-th character of string s, and si..j be the substring of word s, staring at the i-th character and ending at the j-th character (sisi + 1… sj, i ≤ j).

Then the simple prettiness of s is defined by the formula:


The prettiness of s equals

Find the prettiness of the given song title.

We assume that the vowels are I, E, A, O, U, Y.

Input
The input contains a single string s (1 ≤ |s| ≤ 5·105) — the title of the song.

Output
Print the prettiness of the song with the absolute or relative error of at most 10 - 6.

Examples
input
IEAIAIO
output
28.0000000
input
BYOB
output
5.8333333
input
YISVOWEL
output
17.0500000
Note
In the first sample all letters are vowels. The simple prettiness of each substring is 1. The word of length 7 has 28 substrings. So, the prettiness of the song equals to 28.

—————————————————————————————–.
题目大意:
就是求所有子串中元音字母占比的和

解题思路:
这种题很明显就是贡献求解 。
然后对于每一个位置我们考虑如下

s0s1s2s3...sn1
我们只要知道每一个元音字符中所有在的子串都有哪些就好了

对于每一个元音字符我们能够确定在这些区间范围内它贡献1.
e.g.:_si
[0,i],[0,i+1]...[0,n1] ,
[1,i],[1,i+1]...[1,n1]

[i,i],[i,i+1]...[i,n1]

那么结果就是

1i+1i+1+...+1n1
1i1+1i+11+...+1n11

11+12+...+1i

上面的可能看着不太清晰
换成这个看一下就清晰了
11+12+...+1leni+1
—— 12+13+...+1leni+1+1
—— —— 13+14+...+1leni+1+2
——————————————
—— —— —— 1i+1i+1+...+1len .
(总感觉上面那里写错了呢,,,,,)

我们发现这样是很有规律的
我们可以把这个想象成
nj=1ji=11i

通过预处理
我们就能在O(1)的时候计算每个位置的贡献了.
就是把上面的平行四边形部分和变成3个左下为直角的三角形部分和的差的形式.

=========================华丽的分割线==========================
AC之后在standing里面看到另一种做法,
这种做法其实也是求贡献,只不过是以长度做的贡献,
把长度为1 为2 为n 的计算出来再累加起来就是了,
(感觉这样的不是怎么好想。。。所以不要脸的贴过来)
以下盗用这个博客

用数组s来存储前缀和。即s[i]表示前i个字符中元音字母个数,这样可以方便统计区间[l,r]元音字母个数。设串总长为L
则有:
长度为1的子串中元音字母出现的个数之和为:ans[1]=s[L]
长度为2:ans[2]=ans[1]+s[L-1]-s[1]
长度为3:ans[3]=ans[2]+s[L-2]-s[2]
……
最后结果即为 ans[1]/1+ans[2]/2+ans[3]/3+……+ans[L]/L

附本题代码
——————————————–.

//方法一
#include <bits/stdc++.h>
using namespace std;
const int N = 500000+5;
typedef long long int LL;
/***************************************/
double a[N];

bool check(char ch){
    return (ch=='I'||ch=='E'||ch=='A'||ch=='O'||ch=='U'||ch=='Y');
}

int main(){
    string str;
    cin>>str;
    int len = str.length();
    double ans =  0.0,sum = 0.0;
    a[0]=0.0;
    for(int i=1;i<=len;i++){
        sum+=1.0/i;
        a[i]=a[i-1]+sum;
    }
    for(int i=0;i<len;i++){
        if(check(str[i])){
            ans+=a[len]-a[len-i-1]-a[i];
        }
    }
    printf("%.9lf\n",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值