https://codeforces.com/problemset/problem/1105/C
【题意】给定n,l,r,有多少个序列,其和能被3整除
【思路】dp[i][j]表示前i个数,模为j的方案数
l,r很大,不能暴力,思考一下根源如何优化,就是l-r之间有很多数都是能被3整除的,其实是可以一起算的
求[l,r]中能被k除余数为j的个数有=((r+k-j)/k-(l-1+k-j)/k)
【代码】
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 2e5 + 5;
const int mod = 1e9 + 7;
int a[maxn];
ll dp[maxn][3];
int n, l, r;
int main() {
while (~scanf("%d%d%d", &n, &l, &r)) {
memset(dp, 0, sizeof(dp));
for (int h = 0; h <= 2; h++) {
dp[1][h] += ((r - h + 3) / 3 - (l - 1 - h + 3) / 3);
}
for (int i = 1; i < n; i++) {
for (int j = 0; j < 3; j++) {
for (int h = 0; h < 3; h++) {
dp[i + 1][(j + h) % 3] += dp[i][j] * ((r - h + 3) / 3 - (l - 1 - h + 3) / 3);
dp[i + 1][(j + h) % 3] %= mod;
}
}
}
printf("%lld\n", dp[n][0]);
}
}