Codeforces Round #289 (Div. 2, ACM ICPC Rules)E. 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... sji ≤ 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


题意

定义一个字符串的优美度为这个字符串中元音字母所占的比例。

给定一个字符串,对这个字符串所有子串的优美度求和。 

字符串长s (1 <= s <= 500000). 要求结果误差不超过1e-6


题解

求所有的这种字符对答案的贡献。我们可以发现,如果上述的这种字符,所在的位置,从左边数是3,从右边数是4

那么答案就等于

1+1/2+1/3+1/4                            (第一行表示从左边取0个,从右边分别取0,1,2,3个)

     1/2+1/3+1/4+1/5                    (第一行表示从左边取1个,从右边分别取0,1,2,3个)

            1/3+1/4+1/5+1/6             (第一行表示从左边取2个,从右边分别取0,1,2,3个)

那么问题变成了,如何快速求出这个平行四边形里面的数字之和。

我们可以把这个平行四边形的上面和左下角补充完整,变成了一个左下角是直角的三角形。

我们很容易用前缀和记录这个三角形里的数字之和,那么我们可以利用这个来得到这个平行四边形里的数字之和。

直接拿大的三角形减去最上面的那个,就能得到下面这个梯形的数字之和了,然后再减去左下角那个空白三角形就可以了。

左下角空白三角形也是从1开始的,我们也能利用前缀和直接减去,然后就做完了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const int inf=0x3fffffff;
const ll mod=1000000007;
const int maxn=500000+100;
double d[maxn],a[maxn];
char s[maxn];
bool is(char c)
{
    return (c=='A'||c=='E'||c=='I'||c=='O'||c=='U'||c=='Y');
}
int main()
{
    scanf("%s",s+1);
    int l=strlen(s+1);
    double ans=0;
    rep(i,1,maxn) a[i]=a[i-1]+1.0/i;
    rep(i,1,maxn) d[i]=d[i-1]+a[i];
    rep(i,1,l+1)
    {
        if(is(s[i]))
        {
            ans+=d[l]-d[i-1]-d[l-i];
        }
    }
    printf("%.6f\n",ans);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值