zoukankan      html  css  js  c++  java
  • codeforces 509 E. Pretty Song(前缀和+前缀和的前缀和)

    题目链接:http://codeforces.com/problemset/problem/509/E

    题意:给你一个字符串,求字串中包括子串中I, E, A, O, U, Y.所占的概率和。

    题解:有些技巧的题目,关于概率之和可以考虑每个点单独处理然后最终求和。

    假设i点是I, E, A, O, U, Y中的一个。

    以i为终点的概率之和。(字符串从1开始)

    1+1/2+1/3+....1/i=sum[i];

    以i为起点不包括i单点的情况。

    1/2+1/3+....1/(len-i+1)=sum[len-i+1]-sum[1];

    以i为中间点分类讨论。

    字符串中i的位置为2时。

    1/3+1/4+1/5+....1/(len-i+2)=sum[len-i+2]-sum[2];

    位置为3时

    1/3+1/4+1/5+....1/(len-i+3)=sum[len-i+3]-sum[3];

    ....

    位置为i时

    1/(i+1)+1/(i+2)+....1/len=sum[len]-sum[i];

    最后全部加起来

    sum[len]+sum[len-1]+...sum[len-i+1]-(sum[i]+s[i-1]+....sum[1])=tot[len]-tot[len-i]-tot[i];

    (tot表示前缀和的前缀和)

    #include <iostream>
    #include <cstring>
    #include <string>
    using namespace std;
    const int M = 5e5 + 10;
    char s[M];
    double sum[M] , tot[M];
    int main() {
        sum[0] = 0.0;
        for(int i = 1 ; i < M ; i++) {
            sum[i] = 1.0 / i + sum[i - 1];
        }
        tot[0] = 0.0;
        for(int i = 1 ; i < M ; i++) {
            tot[i] = sum[i] + tot[i - 1];
        }
        scanf("%s" , s + 1);
        int len = strlen(s + 1);
        double ans = 0;
        for(int i = 1 ; i <= len ; i++) {
            if(s[i] == 'A' || s[i] == 'E' || s[i] == 'I' || s[i] == 'O' || s[i] == 'U' || s[i] == 'Y') {
                ans += sum[i];
                ans += tot[len] - tot[len - i] - tot[i];
            }
        }
        printf("%.7lf
    " , ans);
        return 0;
    }
    
  • 相关阅读:
    http
    node 学习 http
    socket.io
    每日日报
    每日日报
    每日日报
    06人件读书笔记之一
    每日日报
    每日日报
    05程序员修炼之道:从小工到专家阅读笔记之三
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6839622.html
Copyright © 2011-2022 走看看