509E Pretty Song

E. Pretty Song
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard 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.

Sample test(s)
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, theprettiness of the song equals to 28.

题意:给你一个字符串s,对于每个子串s',simple(s')=元音字符数目/子串长度,最后将各个simple的值相加。

思路:刚开始看到这种数学题很头疼,但细细一推就发现了规律,比如对于EEEEE的字符串,先算对于每个字符的simple分值,对于第一个字符:1+1/2+1/3+1/4+1/5,第二个:1+1/2*2+1/3*2+1/4*2+1/5,第三个:1+1/2*2+1/3*3+1/4*2+1/5,第四个=第二个,第五个=第一个。

对于前一半的字符,数值递增有规律,每次沿两端都少一个1/i,自己可以在取个更长的字符计算找规律验证下。

代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

char s[500013];
double harmonic[500013];

int main()
{
    scanf("%s",&s);
    int len = strlen(s);
    harmonic[0] = 0;
    for (int i=1; i<=len; i++)
        harmonic[i] = harmonic[i-1]+1.0/i;
    double ans = 0;
    double cur = 0;
    for (int i=0; i<len; i++)
    {
        cur+=harmonic[len-i]-harmonic[i];   //这里在后半段时候会成负数减去多余的值
        if (s[i]=='A' || s[i]=='E' || s[i]=='I' || s[i]=='O' || s[i]=='U' || s[i]=='Y')
           ans+=cur;
       // printf("i=%d,cur=%lf,ans=%lf\n",i,cur,ans);
    }
    printf("%1.8f\n",ans);
    return 0;
}

posted @ 2015-02-01 11:56  Doli  阅读(110)  评论(0)    收藏  举报