No three consecutive elements form a strictly increasing or strictly decreasing sequence.
Return the total number of valid ZigZag arrays.
Since the answer may be large, return it modulo109 + 7.
A sequence is said to be strictly increasing if each element is strictly greater than its previous one (if exists).
A sequence is said to be strictly decreasing if each element is strictly smaller than its previous one (if exists).
Example 1:
Input:n = 3, l = 4, r = 5
Output:2
Explanation:
There are only 2 valid ZigZag arrays of length n = 3 using values in the range [4, 5]:
[4, 5, 4]
[5, 4, 5]
Example 2:
Input:n = 3, l = 1, r = 3
Output:10
Explanation:
There are 10 valid ZigZag arrays of length n = 3 using values in the range [1, 3]:
[1, 2, 1], [1, 3, 1], [1, 3, 2]
[2, 1, 2], [2, 1, 3], [2, 3, 1], [2, 3, 2]
[3, 1, 2], [3, 1, 3], [3, 2, 3]
All arrays meet the ZigZag conditions.
Constraints:
3 <= n <= 109
1 <= l < r <= 75
Solutions
Solution 1
Thinking
\(n\) can reach \(10^9\), so a length-by-length DP is impossible; the value range has length \(m=r-l+1\le 75\), which keeps the state space small. A zigzag array forbids equal neighbors and any strictly monotone triple, which means the comparison direction must flip at every step. We therefore encode a state by the last value and last direction (\(2m\) states). The transition is independent of the remaining length, so we build a \(2m\times 2m\) matrix, raise it to the \((n-1)\)-st power, and multiply by the length-\(1\) initial vector.
classSolution{privatestaticfinallongMOD=1_000_000_007L;publicintzigZagArrays(intn,intl,intr){intm=r-l+1;intsize=2*m;long[][]trans=newlong[size][size];for(intx=0;x<m;x++){for(inty=0;y<x;y++){trans[y][m+x]=1;}}// down[x] -> up[y] where y > xfor(intx=0;x<m;x++){for(inty=x+1;y<m;y++){trans[m+y][x]=1;}}long[][]power=matrixPow(trans,n-1);long[]init=newlong[size];for(inti=0;i<m;i++){init[i]=1;init[m+i]=1;}long[]result=multiply(power,init);longans=0;for(longv:result){ans=(ans+v)%MOD;}return(int)ans;}privatelong[]multiply(long[][]mat,long[]vec){intn=mat.length;long[]res=newlong[n];for(inti=0;i<n;i++){longsum=0;for(intj=0;j<n;j++){sum=(sum+mat[i][j]*vec[j])%MOD;}res[i]=sum;}returnres;}privatelong[][]matrixPow(long[][]mat,longexp){intn=mat.length;long[][]res=newlong[n][n];for(inti=0;i<n;i++){res[i][i]=1;}while(exp>0){if((exp&1)==1){res=multiply(res,mat);}mat=multiply(mat,mat);exp>>=1;}returnres;}privatelong[][]multiply(long[][]a,long[][]b){intn=a.length;long[][]res=newlong[n][n];for(inti=0;i<n;i++){for(intk=0;k<n;k++){if(a[i][k]==0)continue;longaik=a[i][k];for(intj=0;j<n;j++){if(b[k][j]==0)continue;res[i][j]=(res[i][j]+aik*b[k][j])%MOD;}}}returnres;}}