Maze (FFT + fast power)

Description

The Vera successively created elves, humans, and dwarves on the Middle-earth Continent. Among them, dwarves live in underground caves all year round. They excavated minerals and even gems, and even created them under the ground with their hard work, bravery and wisdom. The magnificent palace, the intricate labyrinth-well, that's right, now KPM this hairy kid is going to be involved in the labyrinth~
Describe that
KPM found a labyrinth in the kingdom of the dwarves, and now this labyrinth looks like this: the main body of the labyrinth It consists of rooms arranged in a neat matrix of n rows and m columns. The distance between adjacent rooms in the same row or column is 1. We use (x, y) to represent the x-th row and the y-th column Room, and then KPM was surprised to find that the entrance of the maze (not included in the matrix-shaped room) has a channel connection with all the rooms in the first row, and the number of channels connected to the i-th room is a(i) , And then for any two rooms (x, y), (u, v), if and only if the Manhattan distance between the two rooms is not greater than k and is in two adjacent rows, that is |xu|+|yv| <=k, and |xu|=1, the room has direct channel connection, and then according to the XX law of KPM, KPM found that for all the channels from the entrance to the first row of rooms, KPM can only use it from the entrance to the room, but there is no way. Go the other way. For two rooms (x, y), (u, v), if there is an edge between the two rooms, KPM can only walk from the row with the small number of rows to the row with the large number of rows, and also It is necessary to ensure that the number of columns in the rooms he walked through is monotonous and non-decreasing, and if the Manhattan distance between the two rooms is d, the number of directly connected channels between the two rooms is b(d), which means , If KPM can go from (x, y) to (u, v), there must be u=x+1, v>=y, and from (x, y) to (u, v) there is a total of b(v- y+1) channels are directly connected. Now, KPM is boring to know, starting from the entrance and arriving at the i-th room in the nth row, how many ways he has in total. Since he has a phobia of numbers, you only need to tell him the result of the modulo 19 of the answer. That's it.
Input

The first line of input includes three integers n, m, k; the
second line of input includes m integers, where the i-th integer is a(i); the
third line of input includes k integers, where the i-th integer is b (i).
Output

The output includes a line, which includes m integers, where the i-th integer represents the modulus of the number of schemes arriving at (n, i) from the entrance to 19 (note: as long as the direct path sequence is different, it is counted as a different scheme).
Sample Input
3 2 2
3 4
1 2
Sample Output
3 16
Hint

Sample explanation

There is a sequence of S->(1,1)->(2,1)->(3,1) for the room sequence that arrives at (n,1), and there are 3 1 1=3 pathway situations;

There are three types of room sequences that arrive at (n, 2) and they are as follows:

S->(1,1)->(2,1)->(3,2), there are 3 1 2=6 path situations,

S->(1,1)->(2,2)->(3,2), there are 3 2 1=6 path situations,

S->(1,2)->(2,2)->(3,2), use 4 1 1=4 in the channel case,

Therefore, there are always 6+6+4=16 paths to reach (3,2). (Note: S means entrance)

Data scope and agreement

For 10% of the data, ensure that n,m<=1000,k<=10

For the other 20% of the data, ensure that n<=10^18, m<=100

For the other 20% of the data, ensure that n<=10^18, m<=400

For the remaining 50% of the data, ensure that n<=10^18, m<=10000

For 100% data, ensure a(i),b(i)<5,k<=m,min{n,m,k}>0

solution

This title Maze, seeking scheme
has the old routine is a
generally conceivable matrix × matrix, and then fast power
set f [i] [j] f [i] [j]f [ i ] [ j ] : means go toiii linejjj列的方案数
f [ i ] [ j ] = ∑ k = 0 l i m − 1 f [ i − 1 ] [ j − k ] × b [ k ] f[i][j]=\sum_{k=0}^{lim-1}f[i-1][j-k]\times b[k] f[i][j]=k=0l' I m No - 1f[i1][jk]×b[k]
F F T FFT F F T convolution, transfern − 1 n-1n1 time, run with fast power

code

#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
#define mod 19
#define maxn 100005
struct complex {
    
    
	double x, i;
	complex(){
    
    }
	complex( double X, double I ) {
    
    
		x = X, i = I;
	}
}A[maxn], B[maxn];

complex operator + ( complex a, complex b ) {
    
    
	return complex( a.x + b.x, a.i + b.i );
}

complex operator - ( complex a, complex b ) {
    
    
	return complex( a.x - b.x, a.i - b.i );
}

complex operator * ( complex a, complex b ) {
    
    
	return complex( a.x * b.x - a.i * b.i, a.x * b.i + a.i * b.x );
}

double pi = acos( -1.0 );

int len = 1;
int r[maxn];

void FFT( complex *c, int f ) {
    
    
	for( int i = 0;i < len;i ++ )
		if( i < r[i] ) swap( c[i], c[r[i]] );
	for( int i = 1;i < len;i <<= 1 ) {
    
    
		complex omega( cos( pi / i ), f * sin( pi / i ) );
		for( int j = 0;j < len;j += ( i << 1 ) ) {
    
    
			complex w( 1, 0 );
			for( int k = 0;k < i;k ++, w = w * omega ) {
    
    
				complex x = c[j + k], y = w * c[j + k + i];
				c[j + k] = x + y;
				c[j + k + i] = x - y;
			}
		}
	}
}

int m, k;
long long n;
int a[maxn], b[maxn];

int main() {
    
    
	scanf( "%lld %d %d", &n, &m, &k );
	for( int i = 1;i <= m;i ++ )
		scanf( "%d", &a[i] );
	for( int i = 0;i < k;i ++ ) //行已经差了1
		scanf( "%d", &b[i] );
	if( n == 1 ) {
    
    
		for( int i = 1;i <= m;i ++ )
			printf( "%d ", a[i] );
		return 0;
	}
	int l = 0;
	while( len <= ( m << 1 ) ) {
    
    
		len <<= 1;
		l ++;
	}
	for( int i = 0;i < len;i ++ )
		r[i] = ( r[i >> 1] >> 1 ) | ( ( i & 1 ) << ( l - 1 ) );
	for( int i = 0;i <= m;i ++ ) {
    
    
		A[i].x = a[i];
		B[i].x = b[i];
	}
	n --;
	while( n ) {
    
    
		if( n & 1 ) {
    
    
			FFT( A, 1 );
			FFT( B, 1 );
			for( int i = 0;i < len;i ++ ) A[i] = A[i] * B[i];
			FFT( A, -1 );
			FFT( B, -1 );
			for( int i = 0;i < len;i ++ ) {
    
    
				A[i] = complex( ( ( int ) ( A[i].x / len + 0.5 ) ) % mod, 0 );
				B[i] = complex( ( ( int ) ( B[i].x / len + 0.5 ) ) % mod, 0 );
			}
		}
		FFT( B, 1 );
		for( int i = 0;i < len;i ++ ) B[i] = B[i] * B[i];
		FFT( B, -1 );
		for( int i = 0;i < len;i ++ )
			B[i] = complex( ( ( int ) ( B[i].x / len + 0.5 ) ) % mod, 0 );
		for( int i = m + 1;i < len;i ++ ) A[i].x = B[i].x = 0; //注意不要忘记清零
		n >>= 1;
	}
	for( int i = 1;i <= m;i ++ ) printf( "%d ", ( ( int ) ( A[i].x + 0.5 ) + mod ) % mod );
	return 0;
}

Guess you like

Origin blog.csdn.net/Emm_Titan/article/details/113683654