Jesus Is Here(递推规律)

Problem Description
  I’ve sent Fang Fang around 201314 text messages in almost 5 years. Why can’t she make sense of what I mean?
  “But Jesus is here!" the priest intoned.“Show me your messages.”
  Fine, the first message is s1 = “c” and the second one is s2 = “ff”.
  The i-th message is si=si−2+si−1 afterwards. Let me give you some examples.
  s3 = “cff “s4 = " ffcff " and s5 = " cffffcff “.
  “I found the i-th message’s utterly charming,” Jesus said.
  “Look at the fifth message”. s5=“cffffcff” and two “cff” appear in it.
  The distance between the first “cff” and the second one we said, is 5.
  “You are right, my friend,” Jesus said.“Love is patient, love is kind.
  It does not envy, it does not boast, it is not proud. It does not dishonor others, it is not self-seeking, it is not easily angered, it keeps no record of wrongs.
  Love does not delight in evil but rejoices with the truth.
  It always protects, always trusts, always hopes, always perseveres.”
  Listen - look at him in the eye. I will find you, and count the sum of distance between each two different “cff” as substrings of the message.
Input
  An integer T (1≤T≤100), indicating there are T test cases.
  Following T lines, each line contain an integer n (3≤n≤201314), as the identifier of message.
Output
  The output contains exactly T lines.
  Each line contains an integer equaling to:
  ∑i<j:sn[i…i+2]=sn[j…j+2]=‘‘cff"(j−i) mod 530600414,
  where sn as a string corresponding to the n-th message.
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

题意

  已知s1 = cff, s2 = ffcff。已知s[i] = s[i-2] + s[i-1]即串s[i-2] 后面接上串s[i-1],问你第N个串中所有字符c之间的距离之和。

思路

  ^ - ^ 由于博主比较懒,所以mod都省略了
  用 p[i].ans 表示第 i 个串中,所有字符 c 之间的距离;
  用p[i].len 表示第 i 串的长度;
  用p[i].num 表示第 i 串中字符 c 的个数
  用p[i].sum 表示第 i 串中字符 c 的位置之和
  一、很明显递推公式的话 p[i].ans = p[i-1].ans + p[i-2].ans + m;
  m表示当第 i-1 串中的字符 c 和第 i-2 串中的字符 c 的距离之和。
  直接求解可能会有有一点困难,我们折中处理,分别求解第 i-1 串中的字符 c 到连接处的距离,和第 i-2 串中的字符 c 到连接处的距离,然后求和。
  先给出 m = (p[i-2].num*p[i-2].len-p[i-2].sum])p[i-1].num + (p[i-2].nump[i-1].sum).
  简单解释一下,由于资源有限,就~~

来自╰⋛⋋⊱⋋吳⋌⊰⋌⋚╯博客   二、就是p[i].sum的更新问题
  p[i].sum = p[i-2].sum+(p[i-1].sum+p[i-2].len * p[i-1].num);
  我们知道合并是把 si-2串后面连上 si-1,所以改变了原来si-1中 c 的位置,应该都要加上 si-2 的长度

  综上的话,递推关系就是:

p[i].len = (p[i-1].len+p[i-2].len)%MOD;
p[i].num = (p[i-1].num+p[i-2].num)%MOD;
p[i].sum = (p[i-1].sum+p[i-2].sum+(p[i-2].len * p[i-1].num)%MOD)%MOD;
p[i].ans = (p[i-1].ans+p[i-2].ans +(((p[i-2].len*p[i-2].num)-p[i-2].sum)%MOD*p[i-1].num)%MOD+(p[i-1].sum*p[i-2].num)%MOD)%MOD;

AC代码:

#include<iostream>
#include<cstdio>
typedef long long ll;
const int maxn = 201316;
const int MOD = 530600414;
using namespace std;
struct node{
    ll len,num,sum,ans;
}p[maxn];
void getnode(){
    p[3].len = 3,p[3].num = 1,p[3].sum = 1,p[3].ans = 0;	//^-^直接数出来就行了
    p[4].len = 5,p[4].num = 1,p[4].sum = 3,p[4].ans = 0;
    for(int i=5;i<maxn;i++) {
        p[i].len = (p[i-1].len+p[i-2].len)%MOD;
        p[i].num = (p[i-1].num+p[i-2].num)%MOD;
        p[i].sum = (p[i-1].sum+p[i-2].sum+(p[i-2].len * p[i-1].num)%MOD)%MOD;
        p[i].ans = (p[i-1].ans+p[i-2].ans +
                    (((p[i-2].len*p[i-2].num)-p[i-2].sum)%MOD*p[i-1].num)%MOD+
                    (p[i-1].sum*p[i-2].num)%MOD)%MOD;
    }
}
int main(){
    getnode();	//提前打表
    int t;
    cin>>t;
    for(int i=1;i<=t;i++){
        int n;
        scanf("%d",&n);
        printf("Case #%d: %lld\n", i,p[n].ans);
    }
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃夭丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值