zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU 5459 Jesus Is Here(递推)(2015沈阳网赛1010题)

     Sample Input

    9

    5

    6

    7

    8

    113

    1205

    199312

    199401

    201314

     

     

    Sample Output

    Case #1: 5

    Case #2: 16

    Case #3: 88

    Case #4: 352

    Case #5: 318505405

    Case #6: 391786781

    Case #7: 133875314

    Case #8: 83347132

    Case #9: 16520782

    题目要求当前字符串序列中某项里cff前缀两两间差值的和。

    假设已经纪录了cff前缀的位置,

    当前第k个字符串的位置为

    v[1], v[2], …v[cnt(k)]

    其中cnt(k)表示当前字符串cff前缀的个数。

    那么对于k+1

    u[1], u[2], …u[cnt(k+1)]

    然后组合两个串

    v[1], v[2], …v[cnt(k)], u[1]+len(k), u[2]+len(k),…, u[cnt(k+1)]+len(k)

    其中len(k)表示第k个字符串的长度。

    考虑前半部分v的内部差的和为sum(k), 后半部分u的内部和为sum(k+1)

    然后就差交叉部分。

    考虑v[i],

    自然是u[1]+len(k)-v[i] + u[2]+len(k)-v[i] +…+ u[cnt(k+1)]+len(k)-v[i]

    化简得s[k+1]+cnt(k+1)*len(k)-cnt(k+1)*v[i]

    然后对i求和

    cnt(k)*s[k+1]+cnt(k)*cnt(k+1)*len(k)-cnt(k+1)*s[k]

    于是sum就是上面三部分的和。

    然后只需要同时维护s, cnt, len即可。

    s[k+2]=s[k]+s[k+1]+cnt(k+1)*len(k)

    cnt(k+2)=cnt(k+1)+cnt(k)

    len(k+2)=len(k+1)+len(k)

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #define LL long long
    #define MOD 530600414
    
    using namespace std;
    
    const int maxN = 201400;
    int n;
    LL cnt[maxN], s[maxN], len[maxN], sum[maxN];
    
    void init()
    {
        cnt[3] = cnt[4] = 1;
        s[3] = 1; s[4] = 3;
        len[3] = 3; len[4] = 5;
        sum[3] = sum[4] = 0;
        for (int i = 5; i < maxN; ++i)
        {
            cnt[i] = (cnt[i-1]+cnt[i-2])%MOD;
            s[i] = (s[i-1]+s[i-2]+cnt[i-1]*len[i-2]%MOD)%MOD;
            len[i] = (len[i-1]+len[i-2])%MOD;
            sum[i] = (sum[i-1]+sum[i-2])%MOD;
            sum[i] += (cnt[i-2]*s[i-1]%MOD+(cnt[i-2]*cnt[i-1]%MOD)*len[i-2]%MOD-cnt[i-1]*s[i-2]%MOD)%MOD;
            sum[i] = (sum[i]%MOD+MOD)%MOD;
        }
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        init();
        int T;
        scanf("%d", &T);
        for (int times = 0; times < T; ++times)
        {
            scanf("%d", &n);
            printf("Case #%d: %d
    ", times+1, sum[n]);
        }
        return 0;
    }
  • 相关阅读:
    Spring(二) Spring装配Bean的几种方式
    Spring(一) Spring配置文件中classpath和classpath*的区别
    学习响应式编程 Reactor (5)
    学习响应式编程 Reactor (4)
    学习响应式编程 Reactor (3)
    学习响应式编程 Reactor (2)
    学习响应式编程 Reactor (1)
    学习Java 8 Stream Api (5)
    学习Java 8 Stream Api (4)
    Spring WebFlux 学习笔记
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4822178.html
Copyright © 2011-2022 走看看