chiaki sequence reloaded(规律+数位dp)

链接:https://www.nowcoder.com/acm/contest/142/C
来源:牛客网
 

题目描述

Chiaki is interested in an infinite sequence a1, a2, a3, ..., which defined as follows:

Chiaki would like to know the sum of the first n terms of the sequence, i.e. . As this number may be very large, Chiaki is only interested in its remainder modulo (109 + 7).

输入描述:

There are multiple test cases. The first line of input contains an integer T (1 ≤ T ≤ 105), indicating the number of test cases. For each test case:
The first line contains an integer n (1 ≤ n ≤ 1018).

输出描述:

For each test case, output an integer denoting the answer.

示例1

输入

复制

10
1
2
3
4
5
6
7
8
9
10

输出

复制

0
1
2
2
4
4
6
7
8
11

思路:这道题的规律真的是难想。

打表可知,a【i】的值就是i转化成二进制后,相邻两位的值相同就加一,否则减一。

然后就可以用数位dp来写了。

用dp【i】【j】【k】表示第i位,当前位的值是j,当前的和是k

由于k的取值范围是【-64,64】所以用abs(和-64)来代替。

#include <bits/stdc++.h>
using namespace std;
const long long mod=1000000007;
long long i,n,m,dp[64][3][128],a[64],T;
long long dfs(int len,bool maxi,int pre,int sum)
{
    if( dp[len][pre][sum]!=-1 && maxi==0 )
        return dp[len][pre][sum];
    long long cnt=0;
    if(!len)
        return abs(sum-64);///他这里把和都变成了负数的绝对值
    int maxn=maxi?a[len]:1;
    for(int i=0;i<=maxn;i++)
    {
        if(pre==2)
        {
            if(i)
                cnt+=dfs(len-1,maxi&&i==a[len],i,sum);
            else 
                cnt+=dfs(len-1,maxi&&i==a[len],pre,sum);
        }
        else
        {
            if(i==pre)///判断%%%
                cnt+=dfs(len-1,maxi&&i==a[len],i,sum+1);
            else 
                cnt+=dfs(len-1,maxi&&i==a[len],i,sum-1);
        }
    }
    cnt%=mod;
    if(!maxi)
        dp[len][pre][sum]=cnt;
    return cnt;
}
long long div(long long tmp)
{
    int p=0;
    while(tmp)
        a[++p]=tmp%2,tmp/=2;
    return dfs(p,1,2,64);
}
int main()
{
    memset(dp,-1,sizeof(dp));
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld",&n);
        printf("%lld\n",div(n));
    }
    return 0;
}

还有这篇博客讲的也很好。觉得这样写更自由https://blog.csdn.net/jaihk662/article/details/81263085

猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/81292942