CF1105C Ayoub and Lost Array

较为基础的 DP。

考虑 dpi,jdp_{i,j} 表示前 ii 个数中和除 33 余数为 jj 的方案数,其中 j{0,1,2}j \in \{0, 1, 2\}

定义 f(x)f(x) 表示 i=lr[ix(mod3)]\sum \limits_{i=l}^r [i \equiv x \pmod 3],即 llrr 中有多少个数取余 33 余数为 xx

显然有转移方程 dpi,j=k=02dpi1,k×f((j+3k) mod3)dp_{i,j} = \sum_{k=0}^2 dp_{i-1, k} \times f((j+3-k) \bmod 3),其中 mod\bmod 表示取余的结果。

时间复杂度 O(n)O(n)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

const int N = 2e5 + 5;
const long long MOD = 1e9 + 7;

long long l, r, dp[N][3];
int n;

inline long long calc(long long x)
{
	long long ll = l, rr = r;
	if (r - l < 3)
	{
		int cnt = 0;
		for (int i = l; i <= r; i++)
		{
			cnt += (i % 3 == x);
		}
		return cnt * 1ll;
	}
	while (rr % 3 != x) rr--;
	while (ll % 3 != x) ll++;
	return (rr / 3 - ll / 3 + 1) % MOD;
}

int main()
{
	scanf("%d%lld%lld", &n, &l, &r);
	long long x = calc(0), y = calc(1), z = calc(2);
	//printf("%lld %lld %lld\n", calc(0), calc(1), calc(2));
	dp[1][0] = x;
	dp[1][1] = y;
	dp[1][2] = z;
	for (int i = 2; i <= n; i++)
	{
		dp[i][0] = (dp[i - 1][0] * x % MOD + dp[i - 1][1] * z % MOD + dp[i - 1][2] * y % MOD) % MOD;
		dp[i][1] = (dp[i - 1][0] * y % MOD + dp[i - 1][1] * x % MOD + dp[i - 1][2] * z % MOD) % MOD;
		dp[i][2] = (dp[i - 1][0] * z % MOD + dp[i - 1][1] * y % MOD + dp[i - 1][2] * x % MOD) % MOD;
	}
	printf("%lld\n", dp[n][0]);
	return 0;
}
posted @   HappyBobb  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示