fjut3283 NTT快速數論變換

2021-08-22 08:39:12 字數 1538 閱讀 6118

題解:我們將b序列反轉那麼最後就會變成

a0,a1,a2,.....an-1

b0,a1,b2......bn-1

那麼答案將變成a0*bi+a1*bi-1+.....ai*b0+...+ai+1*bn-1+ai+2*bn-2+....an-1*bi+1然後你會發現答案就是多項式乘法,指數相加等於i的係數加上指數相加等於i+n的係數就是答案,因為這題數值較大用fft可能會精度出現問題所以我們選用ntt演算法,接著就是取p和原根了,因為我們這裡最大的數值可能是1e17所以我們選擇5*2^55+1作為p,然後他的原根是6,多項式乘法後列舉每個i後取最大值即可

按平時選擇998244353原根是3即可

這裡有個費馬素數表來自大佬的部落格:

#include#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define mes(a,b) memset(a,b,sizeof(a))

#define rep(i,a,b) for(int i = a; i <= b; i++)

#define dec(i,a,b) for(int i = a; i >= b; i--)

#define pb push_back

#define mk make_pair

#define fi first

#define se second

#define ls rt<<1

#define rs rt<<1|1

#define lson ls,l,mid

#define rson rs,mid+1,r

#define lowbit(x) x&(-x)

typedef double db;

typedef long long int ll;

typedef pairpii;

typedef complexcd;

typedef unsigned long long ull;

const ll inf = 0x3f3f3f3f;

const int mx = 3e5+5;

const int mod = 1e9+7;

const ll p = 180143985094819841;

const int x_move = ;

const int y_move = ;

int n,m;

ll a[mx];

ll b[mx];

int rev[mx];

int bit;

int len;

void init()

ll modadd(ll x,ll n)

ll modexp(ll x,ll n)

return ans;

}void ntt(ll p,int len,int dft)

} }if(dft==-1)

}int main()

fjut 3283 FFT多項式乘法

本題簡單剖析出來就是固定其中乙個串然後另乙個串旋轉到乙個位置值得答案值最大.我們發現每次求值的複雜度是o n 一共有n種旋轉方法,所以總複雜度是o n 2 如果把這n種都綜合起來的話不就是近似多項式乘法了嗎?那麼怎麼轉換呢?看下面的圖 以n 5為例,那麼5種旋轉方式的值分部在多項式的 呢?從圖看出就...

FJUT 2485 數列分段II

timelimit 1000ms memorylimit 128mb 64 bit integer io format lld problem description 對於給定的乙個長度為n的正整數數列a i 現要將其分成m m n 段,並要求每段連續,且每段和的最大值最小。關於最大值最小 例如一數...

FJUT 2399 合唱隊形 雙向lis

合唱隊形 timelimit 1000ms memorylimit 128mb 64 bit integer io format lld n位同學站成一排,老師要請其中的 n k 位同學出列,使得剩下的k位同學排成合唱隊形。合唱隊形是指這樣的一種隊形 設k位同學從左到右依次編號為1,2 k,他們的身...