GDOI2017模擬9 24 週末晚會

2021-07-23 04:52:10 字數 1303 閱讀 8465

求n個點的圓排列,每個點是1或0,並且連續的0不超過k個的方案數。

迴圈同構算一種。多組資料。

t<=50,n,k<=2000

首先,先不考慮環的情況,我們來處理一下連續的k個。

乙個很顯然的想法是,fi,j表示,前i個數,第1個是1且後面j個是0的方案數。

看一下這一位放0還是1就可以推出轉移方程了。

如果是在圓上呢?

那麼我們設ri表示長度為i的圓的方案數。

因為我們保證了第乙個是1,所以列舉圓方案的兩邊加起來為j,那麼就有j+1種方法。 於是r

[i]=

∑j=0

kf[i

][j]

∗(j+

1)然後,我們考慮迴圈同構。

設gi表示長度為i的沒有迴圈節的方法。

然後很顯然可以用容斥解決。

列舉i的迴圈節長度,然後把對應的方案減去。 g[

i]=r

[i]−

∑j|i

,j[j]

所以答案就是∑i

|ng[

i]i

因為考慮迴圈節就是i,所以除掉。

還有,如果k>=n,答案要+1(畢竟無法處理全是0的情況)

#include

#include

#include

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

#define n 2005

using

namespace

std;

typedef

long

long ll;

const

int mo=1e8+7;

ll f[n][n],r[n],g[n],ans;

int n,k,ty;

ll mi(ll x,int y)

int main()

// 1

fo(i,1,n) f[i][0]=0;f[1][0]=1;

fo(i,1,n-1) fo(j,0,k) f[i+1][j+1]=f[i][j],f[i+1][0]=(f[i+1][0]+f[i][j])%mo;

// 2

fo(i,1,n)

fo(i,1,n) fo(j,1,i-1) if (!(i%j)) g[i]=(g[i]-g[j]+mo)%mo;

fo(i,1,n) if (!(n%i)) ans=(ans+g[i]*mi(i,mo-2)%mo)%mo;

printf("%lld\n",ans);

}}

GDOI2017模擬8 12 躲藏

給出乙個n m的網格圖,圖中有一些障礙節點。現在有a個男生和b個女生,還有乙個小標。男生要和女生配對,小標可以和任何乙個人配對。每一對cp 霧 只能待在乙個點。乙個點只能有一對cp。現在給出a b 1個人的初始座標,和他們的移動速度 即移動到4相鄰格仔所需的時間 所有人同時移動,求完成配對的最小時間...

GDOI2017模擬8 12 新車

平面上有乙個數軸,e點為目標點。你現在要開 車從w前往e,每移動1格需要1l油。你的油箱容量為s,初始時裝滿了98 汽油。數軸上有n個加油站,每個加油站提供98 95 92 中的一種。到了加油站你可以選擇加任意數量的油,你的油箱是茲瓷所有油甚至混合油的。你認為98 最吼,95 其次,92 跑的最慢。...

GDOI2017模擬11 5 總結

看到第一題,哇,數論題,不會啊,感覺要跪 正當我迷茫的時候,突然機房斷電了。啪的一聲大家的電腦都黑了!不知所措!沒辦法,只好等等。過了10分鐘左右,來電了,重新看了看第一題,也許是冷靜下來了,發現直接暴力分解質因數就能過!繼續看第二題,在草稿紙上推了一下,要用揹包,一開始以為會超時,但仔細想了想發現...