[NOIP Simulation Test]: Cave (DP + Fast питания)

Название Описание

Sedum пошел в пещеру. Он должен был быть здесь, и сестра, чтобы играть. Пещеру представляет собой кольцо, в общей сложности $ $ п--х узлов, он первоначально $ 0 $ номера узла, вторичные мобильный $ $ I $ I $ он может перейти к шагу в любом направлении. Потому что есть другая важная вещь, чтобы сделать, он должен вернуться на номер $ 0 $ узловой ровно через $ м $ раз, а затем уйти, и теперь он хочет знать, сколько номер программы, формы $ 1e9 + 7 $. (Два варианта считаются разными, если и только если позиция по крайней мере, после определенного этапа Sedum, где разные)


Формат ввода

Строка два целых числа $ N $, $ M $, то есть если эту поверхность.


Формат вывода

Линия целое число, представляющее число аналоговых программ $ 1e9 + 7 $.


образец

Пример ввода 1:

4 6

Пример вывода 1:

0

ввод пробы 2:

707 185547

Пример вывода 2:

588828156


Диапазон данных и советы

За $ 20 \% $ данным, $ м \ leqslant 20 $.
За $ 60 \% $ данным, $ м \ leqslant 1000 $.
За $ 100 \% $ данных, $ м \ leqslant 1e9, п \ leqslant 1000 $.


решение проблемы

Этот вопрос оригинального названия смысл вопросов неправильно, я и был изменен.

$ 40 \% $ алгоритм:

Прямой вывод $ 0 $ тысяч миллионов, и я был в шоке на самом деле есть много точек ~

Сложность Время: $ \ Theta (1) $.

Ожидать Счет: $ 0 $ баллов.

Фактическая оценка: $ 40 $ очков.

$ 60 \% $ алгоритм:

При условии, $ дп [I] [J] $ представляет число шагов программы до $ $ $ I $ J, а затем легко могут быть перечислены переходное состояние уравнение: $ йр [I] [J] = дп [i- 1] [ц] + дп [I-1] [J + I] $.

Сложность Время: $ \ Theta (п \ м раз) $.

Ожидания оценка: $ 60 $ очков.

Текущий счет: $ 60 $ точек (выше в «алгоритм» может быть ниже $ 80 $).

$ 100 \% $ алгоритм:

Прежде чем мы можем только выяснить стадию предварительной обработки $ $ н-случай, затем обрабатывают $ \ влево \ lceil \ гидроразрыва {т} {N} \ право \ rceil $ раза по мощности вспышки, то $ м \ моды п $ шагов дальнейшего насилие отделка, временная сложность не допускаются? Циклическая матрица вау, можно понять, как эмоциональный толчок несколько шагов вправо.

Временная сложность: $ \ Theta (п ^ 2 \ раз \ войти м) $.

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
long long n,m;
long long dp[1001][1001];
long long wzc[1001],flag[1001],ans[1001];
void matrix1()
{
	for(long long i=0;i<n;i++)flag[i]=ans[i],ans[i]=0;
	for(long long i=0;i<n;i++)
		for(long long j=0;j<n;j++)
			ans[(i+j)%n]=(ans[(i+j)%n]+flag[i]*wzc[j]%1000000007)%1000000007;
}
void matrix2()
{
	for(long long i=0;i<n;i++)flag[i]=wzc[i],wzc[i]=0;
	for(long long i=0;i<n;i++)
		for(long long j=0;j<n;j++)
			wzc[(i+j)%n]=(wzc[(i+j)%n]+flag[i]*flag[j]%1000000007)%1000000007;
}
int main()
{
	scanf("%lld%lld",&n,&m);
	dp[0][0]=1;
	for(long long i=1;i<=n;i++)
		for(long long j=0;j<n;j++)
		{
			if((j-i+n)%n==(j+i)%n)dp[i][j]=dp[i-1][(j+i)%n];
			else dp[i][j]=(dp[i-1][(j-i+n)%n]+dp[i-1][(j+i)%n])%1000000007;
		}
	for(long long i=0;i<n;i++)
		wzc[i]=dp[n][i];
	ans[0]=1;
	long long bs=m/n;
	while(bs)
	{
	    if(bs&1)matrix1();
	    matrix2();
	    bs>>=1;
	}
	bs=m%n;
	for(long long i=0;i<n;i++)
		dp[0][i]=ans[i];
	for(long long i=1;i<=bs;i++)
		for(long long j=0;j<n;j++)
		{
			if((j-i+n)%n==(j+i)%n)dp[i][j]=dp[i-1][(j+i)%n];
			else dp[i][j]=(dp[i-1][(j-i+n)%n]+dp[i-1][(j+i)%n])%1000000007;
		}
	printf("%lld",dp[bs][0]);
	return 0;
}

rp++

рекомендация

отwww.cnblogs.com/wzc521/p/11431071.html