C. Ayoub and Lost Array(div 533)

C. Ayoub and Lost Array

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Ayoub had an array aa of integers of size nn and this array had two interesting properties:

  • All the integers in the array were between ll and rr (inclusive).
  • The sum of all the elements was divisible by 33.

Unfortunately, Ayoub has lost his array, but he remembers the size of the array nn and the numbers ll and rr, 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+7109+7 (i.e. the remainder when dividing by 109+7109+7). In case there are no satisfying arrays (Ayoub has a wrong memory), print 00.

Input

The first and only line contains three integers nn, ll and rr (1≤n≤2⋅105,1≤l≤r≤1091≤n≤2⋅105,1≤l≤r≤109) — the size of the lost array and the range of numbers in the array.

Output

Print the remainder when dividing by 109+7109+7 the number of ways to restore the array.

Examples

input

Copy

2 1 3

output

Copy

3

input

Copy

3 2 2

output

Copy

1

input

Copy

9 9 99

output

Copy

711426616

Note

In the first example, the possible arrays are : [1,2],[2,1],[3,3][1,2],[2,1],[3,3].

In the second example, the only possible array is [2,2,2][2,2,2].

说说自己对这题的理解:动态规划求最优化答案。设x、y、z分别为区间内%3==0,%3==1,%3==2的个数

a、b、c、分别为当前i个数之和是3的倍数个数、当前i个数之和是3的倍数余1的个数、当前i个数之和是3的倍数余2的个数。

有了以上前提

那么第i+1个的答案怎么求。第i+1比第i个数多一个数,那肯定是从x、y、z、里面选一个加到 i 数里面,怎么选才是符合答案呢?

维护a:a=长度为i的数列之和是3的倍数的个数  *  x+ 长度为i的数列之和是3的倍数余1的个数 * z(1+2 刚好补全)+长度为i的数列之和是3的倍数余2的个数 * y(2+1)刚好补全。

维护b:长度为i的数列之和是3的倍数的个数*y(0+1 余1)+长度为i的数列之和是3的倍数余1的个数*x(1+0余1)+长度为i的数列之和是3的倍数余2的个数*z(2+2)%3==1)

同理 维护c:长度为i的数列之和是3的倍数的个数*z(0+2 余2)+长度为i的数列之和是3的倍数余1的个数*y(1+1余2)+长度为i的数列之和是3的倍数余2的个数*x(2+0余2)

最后输出a即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int main()
{
	ll a,b,c,x,y,z;
	int n,l,r;
	scanf("%d%d%d",&n,&l,&r);
	x=(r-l+1)/3;
	y=(r-l+1)/3;
	z=(r-l+1)/3;
	for(int i=0;i<(r-l+1)%3;i++)
	{
		if((l+i)%3==0) x++;
		if((l+i)%3==1) y++;
		if((l+i)%3==2) z++;
	}
//	printf("0:%d 1:%d 2:%d\n",x,y,z);
	a=x,b=y,c=z;
	for(int i=2;i<=n;i++)
	{
		ll t1=(a*x%mod+b*z%mod+c*y%mod)%mod;
		ll t2=(a*y%mod+b*x%mod+c*z%mod)%mod;
		ll t3=(a*z%mod+b*y%mod+c*x%mod)%mod;
		a=t1;
		b=t2;
		c=t3;	
	}
	printf("%lld\n",a);
}

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/86589797
今日推荐