Description:
定义一种序列: 共有n个数 且都在 l 到 r 之间, 且他们的和能被3整除,问
给出n (1~2e5),l (1~1e9),r (1~1e9), 有多少种这样的序列。
Input:
n,l,r
Output:
answer mod 1e9+7
Analysis:
由于只考虑加和能被3整除,先将l到r之间的所有数,分成3类并计数,即3k+0,3k+1,3k+2. 然后就可以dp了,设dp[i][j]为i个数组成的序列,各元素加和能被3整除余下j的个数,状态转移不难写为
dp[i][(j + k) % 3] += dp[i-1][j] * a[k] for k=0,1,2; 其中a[i]是指分为3k+i的数的个数
初始条件为 dp[0][0]=1
#include<iostream>
#define _CRT_SECURE_NO_WARNINGS
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
#include<unordered_set>
#include<ctime>
#include<float.h>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
const int INF = 1 << 30;
const int MOD = 1000000007;
const int maxn = 200005;
int dp[maxn][3],n,l,r;
int a[3];
int main() {
while (cin >> n >> l >> r) {
a[0] = r / 3 - (l - 1) / 3;
a[1] = (r + 1) / 3 - l / 3;
a[2] = (r + 2) / 3 - (l + 1) / 3;
dp[0][0] = 1; dp[0][1] = 0; dp[0][2] = 0;
_rep(i,1,n)
_for(j, 0, 3)
_for(k,0,3){
dp[i][(j + k) % 3] = (dp[i][(j + k) % 3] + 1ll * dp[i-1][j] * a[k]%MOD) % MOD;
}
cout << dp[n][0] << endl;
}
return 0;
}