4
20
2013
12

Viterbi算法

今天我在翻DP的时候,意外的发现了这个有趣的东西:-D。

其实很简单……只是居然可以用Dp。而且能做的事情很多。

Category: OI | Tags: 动态规划 数学
4
15
2013
0

【转】FFT

#include <iostream>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxh = 10,maxn = 1<<maxh,P = 12289;
const int g=10302,ig = 8974,ninv = 12277;
typedef long long ll;
struct fft{
    ll omg[maxn],iomg[maxn],inv[maxn];
    void initialize(){
        for(int i=0;i<maxn;i++) inv[i] = getinv(i);
        omg[0] = 1,iomg[0] = 1;
        for(int i=1;i<maxn;i++)
            omg[i] = omg[i-1]*g%P,iomg[i] = iomg[i-1]*ig%P;
    }
    ll getinv(ll x){
        ll ans = 0;
        for(int i=0;i<maxh;i++)
            ans |= (x>>i&1)<<maxh-i-1;
        return ans;
    }
    ll f[2][maxn];
    void ft(ll *o,ll *cof,ll *output){
        for(int i=0;i<maxn;i++) f[0][i] = cof[inv[i]];
        for(int h=1;h<=maxh;h++)
            for(int i=0;i<maxn;i++)
                f[h&1][i] = (f[h&1^1][~(1<<h-1)&i]+o[i<<maxh-h&maxn-1]*f[h&1^1][i|1<<h-1]%P)%P;
        for(int i=0;i<maxn;i++) output[i] = f[maxh&1][i];
    }void dft(ll *cof,ll *output){ft(omg,cof,output);}
    void idft(ll *cof,ll *output){ft(iomg,cof,output);for(int i=0;i<maxn;i++) output[i] = output[i]*ninv%P;}
}F;
ll cof1[maxn],cof2[maxn];
char input[maxn],input2[maxn];
int n;
void Init(){
    int len;
    gets(input2);len = strlen(input2);
    for(int i=0;i<len;i++) input[i] = input2[len-i-1];
    for(int i=0;i<len;i++) cof1[i] = input[i]-'0';
    gets(input2);len = strlen(input2);
    for(int i=0;i<len;i++) input[i] = input2[len-i-1];
    for(int i=0;i<len;i++) cof2[i] = input[i]-'0';
}
void solve(){
    F.initialize();
    F.dft(cof1,cof1);F.dft(cof2,cof2);
    for(int i=0;i<maxn;i++) cof1[i] = cof1[i]*cof2[i]%P;
    F.idft(cof1,cof1);
    int jw = 0;
    for(int i=0;i<maxn;i++){
        cof1[i] += jw%10,jw/=10;
        jw+=cof1[i]/10,cof1[i]%=10;
    }
    bool flag = false;
    for(int i=maxn-1;i>=0;i--){
        if(cof1[i]!=0) flag = true;
        if(flag) printf("%c",cof1[i]+'0');
    }
}
int main(){
    freopen("test.in","r",stdin);
    freopen("test.out","w",stdout);
 
    Init();
    solve();
 
    fclose(stdin);
    fclose(stdout);
    return 0;
}
Category: OI | Tags: 数学
4
2
2013
3

Lucas定理——求组合数取模

考虑n! mod p

n! mod p

 = (1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * ... n) mod p

 = (1 * 2 * 3 * ... * p * p+1 * p+2 * ... * 2p * 2p+1 * 2p+2 * 2p+3 * ...) mod p

 = (1 * 2 * 3 * ... * p-1 * p+1 * p+2 * ... * 2p-1 * 2p+1 * ... *p^(n/p-1)* (2*3*...*n/p) ) mod p

其中

1 * 2 * 3 * ... p-1 mod p = p+1 * p+2 * p+3 * p+4 ... * 2p-1 mod p = ... = (n%p!) mod p

相当于每p段加上p,所以全部约掉,就是n%p! mod p。

所以,只需要计算C(n%p,m%p) * Lucas(n/p,m/p)

简化: 

C(N,M) mod p=C(Np0,Mp0)*C(Np1,Mp1) * C(Npx,Mpx)

NpX,MpX表示N和M在p进制下的第 X 位。

----------------------------------------------------------------------------------------------------------------------------------------

扩展,求C(N,M) MOD P^c

……前面变成p^c周期……然后单独处理周期。。
Category: OI | Tags: 数学

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com