GDOI2018模擬8 11 決戰

2021-08-06 02:38:03 字數 1437 閱讀 5704

聽說暴力狀壓可以過?然而我常數不好只有90分

考慮普通的狀壓,f[i][s][j]表示當前填到第i行,第i行的狀態為s,用了j個哲學♂家的方案數

我們把最後一維看做多項式,用x^j的係數表示答案

咦?模數是998244353哦,那我們是不是可以用ntt加速呢?

如果我們求出對於所有wi

,答案的多項式的點值,我們就可以通過一次插值來還原出原多項式

求點值直接dp就可以了,位移相當於乘上w的冪。但是這樣會t

怎麼辦呢?發現這樣dp可以矩陣乘法加速,於是速度就起飛了~~

#pragma gcc optimize(2)

#include

#include

#include

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

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

using

namespace

std;

typedef

long

long ll;

const

int n=2.5*1e3+5,mo=998244353;

int n,m,len,lg,ni,a[3][3],b[9],c[9][9],cnt[9],pw[4];

int t[n*6],w[n*6],ans[n*6],an[9];

struct matrix

}g,f;

bool ok(int x)

bool check(int x,int y)

int mi(int x,int y)

void pwr(int y)

void dft(int *a,int flag)

for(int m=2;m<=len;m*=2) }}

fo(i,0,len-1) a[i]=t[i];

if (flag==-1) fo(i,0,len-1) a[i]=(ll)a[i]*ni%mo;

}void prepare()

int dp(int w)

fo(j,1,b[0])

fo(k,1,c[j][0])

(f.a[j][c[j][k]]+=pw[cnt[c[j][k]]])%=mo;

memcpy(g.a,f.a,sizeof(f.a));

pwr(n-1);

fo(i,1,b[0])

fo(j,1,b[0])

(res+=(ll)an[i]*g.a[i][j]%mo)%=mo;

return res;

}int main()

GDOI2018模擬7 8 質數

將1 n分成盡可能小的集合,使得每個集合的元素均為質數 乙個數n n 6000 第一行乙個數m表示分成幾塊 第二行n個1 m的數表示每個數分到哪一塊 2 1 2 2 1 1 1 1 2 這題很有趣 我們知道有個哥德 猜想 任意乙個足夠大的偶數可以分成兩個質數的和 由於目前人類沒有證明出它是錯的,而且...

GDOI2018模擬8 14 神奇的矩陣

輸出一行表示答案 3 3 2 1 2 3 4 5 6 7 8 9 真是神奇的一道題 為了避免絕對值的影響,讓每個數字從小到大加入,對於每個數字考慮貢獻 設f i j 表示以 i,j 為左上角的k k的矩陣中有數的個數 那麼乙個數在加入時,所有包括它的k k矩陣的f的和,就是這個數對答案做的正貢獻 那...

GDOI2018模擬9 14 通訊

比賽沒有仔細想,碼了個n2 暴力,結果還被卡常了。暴力思路如下 先列舉根為x,依次加入x 1,x 2,x 3 加入乙個點y y x 時,如果它的子樹中沒有已經加入的點,那麼它就會使距離增大,再暴力往上跳,給它的祖先打上標記,直到到某個點,這個點已經被打上標記就可以停止了,同時可以算出增加的距離。感覺...