1. 程式人生 > 實用技巧 >POJ-1430 Binary Stirling Numbers(數學+斯特林數)

POJ-1430 Binary Stirling Numbers(數學+斯特林數)

題目描述

  判斷第二類斯特林數 \(S(n,m)\) 的奇偶性(\(1\leq T\leq 200,1\leq m\leq n\leq 10^9\))。

  \(S(0,0)=1;S(n,0)=0(n>0);S(0,m)=0(m>0)\)

  \(S(n,m)=mS(n-1,m)+S(n-1,m-1)(n,m>0)\)

分析

  設 \(S^{\ast}(n,m)\)\(S(n,m)\) 在模 \(2\) 意義下的值。

  當 \(m\) 是偶數時,\(S^{\ast }(n,m)=S^{\ast }(n-1,m-1)\);當 \(m\) 是奇數時,\(S^{\ast}(n,m)=S^{\ast }(n-1,m)+S^{\ast }(n-1,m-1)=S^{\ast }(n-1,m)+S^{\ast }(n-2,m-2)\)

  因此遞推式的結果與第 \(m\) 和第 \(m-2\) 列有關,打表,把列號為奇數的列單獨拿出來看。

  第一列為 \(\dbinom{n}{0}\),第三列為 \(\dbinom{n-2}{1}\),第五列為 \(\dbinom{n-3}{2}\),歸納得到第 \(n\) 列為 \(\dbinom{n-\frac{m}{2}-1}{\frac{m+1}{2}-1}\)

  把行號為偶數的列單獨拿出來看。

  第二列為 \(\dbinom{m-2}{0}\),第四列為 \(\dbinom{n-3}{1}\),第六列為 \(\dbinom{n-4}{2}\),歸納得到第 \(m\) 列為 $\dbinom{n-\frac{m}{2}-1}{\frac{m+1}{2}-1} $。

  因此當 \((n-\frac{m}{2}-1)\& (\frac{m+1}{2}-1)=n-\frac{m}{2}-1\) 時,\(S(n,m)\) 為奇數,否則為偶數(用Lucas 定理證明)。

程式碼

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    /*S[0][0]=1;
    for(int i=1;i<=100;i++)
        for(int j=1;j<=i;j++)
            S[i][j]=S[i-1][j-1]+j*S[i-1][j];
    for(int i=1;i<=100;i++)
    {
        for(int j=1;j<=i;j++)
        {
            if(j%2==0)
                S[i][j]=S[i-1][j-1];
            else
                S[i][j]=S[i-1][j]+S[i-1][j-1];
        }
    }
    for(int i=1;i<=20;i++)
    {
        if(i<=9)
            cout<<"n="<<i<<"  ";
        else
            cout<<"n="<<i<<" ";
        for(int j=1;j<=i;j+=2)
            cout<<S[i][j]<<" ";
        cout<<endl;
    }
    for(int i=1;i<=20;i++)
    {
        if(i<=9)
            cout<<"n="<<i<<"  ";
        else
            cout<<"n="<<i<<" ";
        for(int j=2;j<=i;j+=2)
            cout<<S[i][j]<<" ";
        cout<<endl;
    }*/
    int T;
    cin>>T;
    while(T--)
    {
        long long n,m;
        cin>>n>>m;
        if(m>n)
        {
            puts("0");
            continue;
        }
        else if(n==m)
        {
            puts("1");
            continue;
        }
        else if(n*m==0)
        {
            puts("0");
            continue;
        }
        long long x=n-m/2-1;
        long long y=(m+1)/2-1;
        if((x&y)==y)
            puts("1");
        else
            puts("0");
    }
    return 0;
}