記些東西

1、寫FFT時需要對N位二進制翻轉,我一直都是開一個rev數組預處理來搞的,如下

  for (N=2, M=1;N<(n+m);N<<=1, M++);
  for (i=0;i<N;i++){
  	int len=0;
  	for (j=i;j>0;j>>=1) dig[len++]=(j&1);
  	for (j=0;j<M;j++) rev[i]=( (rev[i]<<1)|dig[j] );
  }

如果一個程序裏需要進行多個不同長度的FFT,每次都預處理的話程序不免變得冗長。

今天學了一個很叼的方法。雖然乍一看一點都不懂,但實際上就是模擬倒着給最高位+1並進位給低位的過程,如下:

  for (int i=1,j=0;i<N-1;i++){
    for (int s=N; (~j) & s;j^=(s>>=1));
    if (i>j) swap(A[i], A[j]);
  }

(感覺FFT變得美觀多了得意

2、做題時看到的,詢問有n個節點的環大小爲k的獨立集的個數。

先把環搞成鏈。考慮選出k個點後,在每個點之前放一個空點,這樣一定是合法的(頭和尾不會同時被選)。去除要加的k個空點,一共有n-k個點可以選擇。發案數爲C(n-k,k)

不過我們發現這樣選出的獨立集一定不會覆蓋到第一個點(拉成鏈後的第一個點)。強行把第一個點加進去微笑

注意到此時最後一個點是不能選的,供選擇的點一共有:n-1-1-(k-1) = n-k-1,我們要從中選擇出k-1個點,這部分方案數爲C(n-k-1,k-1)

所以我們得出公式,n個節點的環大小爲k的獨立集的個數爲  C(n-k,k)+C(n-k-1,k-1)

好吧,我承認用dp做法也很簡單。。。。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章