zoukankan      html  css  js  c++  java
  • 【LOJ】#3090. 「BJOI2019」勘破神机

    LOJ#3090. 「BJOI2019」勘破神机

    为了这题我去学习了一下BM算法。。

    很容易发现这2的地方是(F_{1} = 1,F_{2} = 2)的斐波那契数列

    3的地方是(G_{1} = 3,G_{2} = 11)其中下标表示长度的(frac{1}{2}),可以得到(G_{3} = 4G_{2} - G_{1})

    然后我们列一波特征根方程,可以得到

    (m = 2)

    [left{egin{matrix} x_{1} = frac{1 + sqrt{5}}{2} \ x_{2} = frac{1 - sqrt{5}}{2} \ c_{1} = frac{5 + sqrt{5}}{10} \ c_{2} = frac{5 - sqrt{5}}{10} end{matrix} ight. ]

    (m = 3)

    [left{egin{matrix} x_{1} = 2 + sqrt{3} \ x_{2} = 2 - sqrt{3} \ c_{1} = frac{3 + sqrt{3}}{6} \ c_{2} = frac{3 - sqrt{3}}{10} end{matrix} ight. ]

    然后我们会可以把阶乘(n(n - 1)(n - 2)...(n - k + 1))当成一个k次多项式

    然后暴力算出每一项的系数,然后我们要算的就是

    (sum_{i = l}^{r} f_{i}^{k})

    然后把通项带进去

    (sum_{i = l}^{r} (c_{1}x_{1}^{i} + c_{2}x_{2}^{i})^{k})

    (sum_{i = l}^{r}sum_{j = 0}^{k}inom{k}{j}c_{1}^{j}x_{1}^{ij}c_{2}^{k - j}x_{2}^{i(k - j)})

    (sum_{j = 0}^{k}inom{k}{j}c_{1}^{j}c_{2}^{k - j}sum_{i = l}^{r}(x_{1}^{j}x_{2}^{k - j})^{i})

    后面是等比数列求和,算一下就好了

    复杂度是(k^{2}log r)

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define MAXN 2005
    #define ba 47
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    const int MOD = 998244353;
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    void update(int &x,int y) {
        x = inc(x,y);
    }
    int fpow(int x,int c) {
        int res = 1,t = x;
        while(c) {
    	if(c & 1) res = mul(res,t);
    	t = mul(t,t);
    	c >>= 1;
        }
        return res;
    }
    template<int T>
    struct Complex {
        int r,i;
        Complex(int _r = 0,int _i = 0) {r = _r;i = _i;}
        friend Complex operator + (const Complex &a,const Complex &b) {
    	return Complex(inc(a.r,b.r),inc(a.i,b.i));
        }
        friend Complex operator - (const Complex &a,const Complex &b) {
    	return Complex(inc(a.r,MOD - b.r),inc(a.i,MOD - b.i));
        }
        friend Complex operator * (const Complex &a,const Complex &b) {
    	return Complex(inc(mul(a.r,b.r),mul(T,mul(a.i,b.i))),inc(mul(a.r,b.i),mul(b.r,a.i)));
        }
        friend Complex fpow(Complex x,int64 c) {
    	Complex res(1,0),t = x;
    	while(c) {
    	    if(c & 1) res = res * t;
    	    t = t * t;
    	    c >>= 1;
    	}
    	return res;
        }
        friend Complex Query(Complex x,int64 n) {
    	if(x.r == 1 && !x.i) return (n + 1)% MOD;
    	Complex u = 1 - fpow(x,n + 1),d = 1 - x,t;
    	t = d;t.i = MOD - t.i;
    	int iv = fpow((t * d).r,MOD - 2);
    	u = u * t * iv;
    	return u;
        }
    };
    int m,k,f[1005],fac[1005],invfac[1005];
    int64 l,r;
    int C(int n,int m) {
        if(n < m) return 0;
        return mul(fac[n],mul(invfac[m],invfac[n - m]));
    }
    namespace mequal2 {
        Complex<5> x1,x2,c1,c2;
        void Main() {
    	int inv2 = fpow(2,MOD - 2),inv10 = fpow(10,MOD - 2);
    	x1 = Complex<5>(inv2,inv2);x2 = Complex<5>(inv2,MOD - inv2);
    	c1 = Complex<5>(mul(5,inv10),inv10);c2 = Complex<5>(mul(5,inv10),MOD - inv10);
    	int ans = mul(invfac[k],fpow((r - l + 1) % MOD,MOD - 2));
    	Complex<5> res;
    	for(int j = 1 ; j <= k ; ++j) {
    	    Complex<5> s;
    	    for(int h = 0 ; h <= j ; ++h) {
    		Complex<5> t = C(j,h) * fpow(c1,h) * fpow(c2,j - h),q = fpow(x1,h) * fpow(x2,j - h),p;
    		p = Query(q,r) - Query(q,l - 1);
    		s = s + t * p;
    	    }
    	    res = res + s * f[j];
    	}
    	ans = mul(ans,res.r);
    	out(ans);enter;
        }
    }
    namespace mequal3 {
        Complex<3> x1,x2,c1,c2;
        void Main() {
    	int inv6 = fpow(6,MOD - 2);
    	x1 = Complex<3>(2,1);x2 = Complex<3>(2,MOD - 1);
    	c1 = Complex<3>(mul(3,inv6),inv6);c2 = Complex<3>(mul(3,inv6),MOD - inv6);
    	int ans = mul(invfac[k],fpow((r - l + 1) % MOD,MOD - 2));
    	r = r / 2;
    	if(l & 1) l = (l + 1) / 2;
    	else l = l / 2;
    	
    	Complex<3> res;
    	if(l <= r) {
    	    for(int j = 1 ; j <= k ; ++j) {
    		Complex<3> s;
    		for(int h = 0 ; h <= j ; ++h) {
    		    Complex<3> t = C(j,h) * fpow(c1,h) * fpow(c2,j - h),q = fpow(x1,h) * fpow(x2,j - h),p;
    		    p = Query(q,r) - Query(q,l - 1);
    		    s = s + t * p;
    		}
    		res = res + s * f[j];
    	    }
    	}
    	ans = mul(ans,res.r);
    	out(ans);enter;
        }
    }
    void Solve() {
        read(l);read(r);read(k);
        memset(f,0,sizeof(f));
        f[1] = 1;
        for(int i = 1 ; i < k ; ++i) {
    	for(int j = i + 1 ; j >= 1 ; --j) {
    	    f[j] = inc(mul(MOD - i,f[j]),f[j - 1]);
    	}
        }
        if(m == 2) mequal2::Main();
        else mequal3::Main();
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        int T;
        read(T);read(m);
        fac[0] = 1;
        for(int i = 1 ; i <= 1000 ; ++i) fac[i] = mul(fac[i - 1],i);
        invfac[1000] = fpow(fac[1000],MOD - 2);
        for(int i = 999 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1);
        for(int i = 1 ; i <= T ; ++i) {
    	Solve();
        }
    }
    
  • 相关阅读:
    mac zsh选择到行首的快捷键
    phalcon下拉列表
    tinycore remaster方法
    bundle安装方法
    centos7安装avahi
    pydoc介绍
    macosx下apache的默认用户为daemon
    centos配置ssh免密码登录后,仍提示输入密码
    xampp默认项目文件夹htdocs
    微信开发:"errcode": -1000,"errmsg": "system error"错误的解决办法
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10984467.html
Copyright © 2011-2022 走看看