Meaningless Sequence Gym - 102832D

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Meaningless Sequence Gym - 102832D相关的知识,希望对你有一定的参考价值。

Meaningless Sequence Gym - 102832D

题意:

给你n和c,an的公式如下图
在这里插入图片描述
让你求a0+…an的和,mod 1e9+7

题解:

训练时推了好一阵子才和队友推出
我看网上正解为:
一个数的大小与它的二进制表示中的1的个数有关
a=c(二进制中1的个数)
问题就变成了转化为求所有数中1的个数,
dp[i][j]为考虑i~n位,有j个1的情况有多少种,然后数位dp跑,详细可以看代码

训练时我们是找到了规律,我通过列出1~20的ai答案,发现规律,比如7,对应的二进制是111,那么它就等于去掉最高位剩下部分对应的数乘c,111去掉最高位就是011,也就是3,而3对应的是c2,所以7就是c3,(当然3也可以通过这个方法得到),边界就是00对应1,01对应c
而且还有规律,第一位+第二位的和乘以c就是第三位加第四位的和,前四位的和乘c,就是5到8位的和,也就是sum=(c+1),sum+=sum*c,看几轮
在这里插入图片描述
根据这些性质我们就可以算出答案,比如1000(二进制),我们可以计算出111部分的答案,就是sum=(c+1),进行两轮的sum+=sum * c,然后让1100减去111,得到0101,重复这个过程,先计算11的答案,然后减11,一值重复,直到最后位,最后得到答案(不是很明白的可以看看代码)

代码:

数位dp

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int mod = 1e9 + 7;
typedef long long ll;
char a[3005];
int n;
ll dp[3005][3005],c;

ll qpow(ll x,ll n) {
    ll res = 1;
    if(n == -1) return 0;
    while(n) {
        if(n & 1) {
            res = res * x % mod;
        }
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}

ll dfs(int len,int sum,bool limit) {
    if(sum < 0) return 0;
    if(sum > n - len + 1) return 0;
    if(len == n + 1) {
        return sum == 0;
    }
    if(!limit && dp[len][sum] != -1) return dp[len][sum];

    int up = (limit ? (a[len] - '0') : 1);
    ll ans = 0;
    for(int i = 0;i <= up;i++) {
        ans += dfs(len + 1,sum - (i == 1),limit && i == up);
        ans %= mod;
    }
    return limit ? ans : dp[len][sum] = ans;
}

int main() {
   scanf("%s%lld",a + 1,&c);
   n = strlen(a + 1);
   memset(dp,-1,sizeof(dp));
   ll ans = 0;
   for(int i = 0;i <= n;i++) {
     ll num = dfs(1,i,true);
     ans = (ans + num * qpow(c,i) % mod) % mod;
   }
   printf("%lld\\n",ans);
    
    return 0;
}

规律递推代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const int mod=1e9+7;
ll poww(ll a,ll b){
	ll ans=1;
	while(b){
		if(b&1)
			ans*=a%mod;
		a*=a%mod;
		b>>=1;
	}
	return ans%mod;
}	
string s;ll c;
ll cal(int len){
	ll sum=(c+1)%mod;
	for(int i=1;i<len;i++){
		sum=(sum+sum*c%mod)%mod;
	}
	return sum;
}

int main(){
	cin>>s>>c;
	ll sum=0;
	int len=s.length();
	if(s[len-1]=='0'){
		sum=1;
	}
	else sum=c+1;
	for(int i=len-2;i>=0;--i){
		if(s[i]!='0'){
			sum=sum*c%mod;
			sum=(sum+cal(len-i-1))%mod;
		}
//		cout<<sum<<endl;
	}
//	sum+=cal(len-1);
//	for(int i=0;i<len;i++){
//		if(n[i]=='1')
//			sum+=cal(len-i-1);
//	}
	cout<<sum;
	return 0;
}

以上是关于Meaningless Sequence Gym - 102832D的主要内容,如果未能解决你的问题,请参考以下文章

Histogram Sequence Gym - 102059J

Gym101158A Rearranging a Sequence(思维)

Gym 240084E - Correct Bracket Sequence Editor - [线段树]

Codeforces 833A The Meaningless Game

CF1110C Meaningless Operations

CF833A The Meaningless Game 鎬濈淮