Ayoub and Lost Array
Ayoub had an array a of integers of size n and this array had two interesting properties:
All the integers in the array were between l and r (inclusive).
The sum of all the elements was divisible by 3.
Unfortunately, Ayoub has lost his array, but he remembers the size of the array n and the numbers l and r, so he asked you to find the number of ways to restore the array.
Since the answer could be very large, print it modulo 109+7 (i.e. the remainder when dividing by 109+7). In case there are no satisfying arrays (Ayoub has a wrong memory), print 0.
題目大意:求數組個數,這個數組要求長度爲n,數組裏面的數大小在 [l,r] 區間,並且數組和可以整除3;
數學思維,沒有想到很難做;
從可以整除3入手,可以先預處理出 [l,r] 區間裏面所有數餘0,餘1,餘2 的個數,那麼可以定義狀態轉移方程爲:
dp[i][j] 表示前 i 個數和餘 j 的種類數;
(dp[i][0]=dp[i-1][0]*sum0+dp[i-1][1]*sum2+dp[i-1][2]*sum1)%=mod;
(dp[i][1]=dp[i-1][0]*sum1+dp[i-1][1]*sum0+dp[i-1][2]*sum2)%=mod;
(dp[i][2]=dp[i-1][0]*sum2+dp[i-1][1]*sum1+dp[i-1][2]*sum0)%=mod;
十分巧妙;
代碼:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=200100;
const int M=2000100;
const LL mod=1e9+7;
int sum0,sum1,sum2;
LL dp[N][3];
int main(){
int n,l,r;cin>>n>>l>>r;
sum0=r/3-l/3;
if(l%3==0) sum0++;
sum1=(r+2)/3-(l+2)/3;
if(l%3==1) sum1++;
sum2=(r+1)/3-(l+1)/3;
if(l%3==2) sum2++;
dp[1][0]=sum0,dp[1][1]=sum1,dp[1][2]=sum2;
for(int i=2;i<=n;i++){
(dp[i][0]=dp[i-1][0]*sum0+dp[i-1][1]*sum2+dp[i-1][2]*sum1)%=mod;
(dp[i][1]=dp[i-1][0]*sum1+dp[i-1][1]*sum0+dp[i-1][2]*sum2)%=mod;
(dp[i][2]=dp[i-1][0]*sum2+dp[i-1][1]*sum1+dp[i-1][2]*sum0)%=mod;
}
cout<<dp[n][0]<<endl;
return 0;
}