给定三个数n,l,r (1≤n≤2⋅105,1≤l≤r≤109)
求[l,r]之间选n个数求和能被3整除的方案数,其中可以重复选取,考虑选取顺序。
结果对1e10+7取模
#include<bitsstdc++.h>
using namespace std;
const int maxn=2e5+5;
long long dp[maxn][3];
const long long mod=1e9+7;
int main()
{
int n,l,r;
scanf("%d%d%d", &n, &l, &r);
容斥原理
int a0=r/3-(l-1)/3;//l,r这个区间对3取余等于0的个数
int a1=(r+2)/3-(l+1)/3;//l,r这个区间对3取余等于1的个数
int a2=(r+1)/3-l/3;//l,r这个区间对3取余等于2的个数
dp[1][0]=a0;
dp[1][1]=a1;
dp[1][2]=a2;
dp[i][j]表示选取长度为i个数,求和取余为j的方案数。
for(int i=2; i<=n; i++)
{
dp[i][0]=(dp[i-1][0]*a0+dp[i-1][1]*a2+dp[i-1][2]*a1)%mod;
dp[i][1]=(dp[i-1][0]*a1+dp[i-1][1]*a0+dp[i-1][2]*a2)%mod;
dp[i][2]=(dp[i-1][0]*a2+dp[i-1][1]*a1+dp[i-1][2]*a0)%mod;
}
printf("%lld", dp[n][0]%mod);
}