• 题解 HDU 6966 I love sequences


    传送门


    【大意】

    给定 (n) 和三个下标从 (1) 开始,长度为 (n) 的数列 (a, b, c)

    对于整数 (p), 我们构造数列 (displaystyle d_{p,k}=sum_{iotimes j=k}a_ib_j(1leq i, jleq{nover p}))

    其中,位运算 (iotimes j) 表示 (i)(j) 在三进制意义下按位取 (gcd),即 (k_t=gcd(i_t, j_t))

    现要求求出 (displaystyle sum_{p=1}^nsum_{k=1}^{+infty} d_{p, k}cdot c_p^k)


    【分析】

    比较显然的广义FWT

    前置推导知识参考本人博客 关于 FWT 的一些理解

    需要构造三阶方阵使得 (T_{C(n, gcd(p,q)} )=T_{A(n, p)}T_{B(n, q)})

    由于为三进制,故仅需寻找一种构造,使得:

    (T_C=left( egin{matrix} T_{C(0,0)}&T_{C(0,1)}&T_{C(0,2)} \\ T_{C(1,0)}&T_{C(1,1)}&T_{C(1,2)} \\ T_{C(2,0)}&T_{C(2,1)}&T_{C(2,2)} end{matrix} ight)) 为可逆矩阵即可

    具体推导过程见后文,这里直接给出一组解: (T_A=T_B=T_C=left( egin{matrix} 1&0&0 \\ 1&1&1 \\ 1&0&1 end{matrix} ight)) ,逆矩阵 (T_C^{-1}=left( egin{matrix} 1&0&0 \\ 0&1&-1 \\ -1&0&1 end{matrix} ight))

    由此,对 (a,b) 的前 ({nover p}) 项提取出来,进行 FWT 变换为 (T_Aa,T_Bb) 后直接点积,求出 (T_Cd)

    再由 (d=T_C^{-1}cdot T_Cd) 进行 UFWT 求出 (d) 数列

    之后由秦九韶定理,可以 (O({nover p})) 直接跑出第二个求和符号内的结果

    总时间复杂度为 (displaystyle T(n)=sum_{p=1}^n[O({nover p}log{nover p})+O({nover p})]=O(nlog^2 n))


    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> pii;
    typedef double db;
    #define fi first
    #define se second
    const int MOD=1e9+7, MAXN=6e5+10;
    inline int add(int a, int b) { return (a+=b)>=MOD?a-MOD:a; }
    inline int dis(int a, int b) { return (a-=b)<0?a+MOD:a; }
    
    int n, a[MAXN], b[MAXN], c[MAXN], d[MAXN], aa[MAXN], bb[MAXN];
    inline void exFWT(int *a, int N, int flag){
        for(int i=1;i<N;i*=3) for(int S=0; S<N; ++S)
            if( (S/i)%3==0 ){
                int x=a[S], y=a[S+i], z=a[S+i+i];
                if(!flag){
                    a[S+i+i]=add(x, z);
                    a[S+i]=add(a[S+i+i], y);
                    a[S]=x;
                }
                else{
                    a[S]=x;
                    a[S+i]=dis(y, z);
                    a[S+i+i]=dis(z, x);
                }
            }
    }
    inline int calc(int n, int c){
        int N=1;
        while(N<=n) N*=3;
    
        for(int i=0;i<=n;++i) aa[i]=a[i]; for(int i=n+1;i<N;++i) aa[i]=0;
        for(int i=0;i<=n;++i) bb[i]=b[i]; for(int i=n+1;i<N;++i) bb[i]=0;
        exFWT(aa, N, 0); exFWT(bb, N, 0);
        for(int i=0;i<N;++i) d[i]=(ll)aa[i]*bb[i]%MOD;
        exFWT(d, N, 1);
    
        int res=0;
        for(int i=0, bas=1;i<N;++i, bas=(ll)bas*c%MOD)
            res=add(res, (ll)bas*d[i]%MOD);
        return res;
    }
    inline int ans(){
        for(int i=1;i<=n;++i) cin>>a[i];
        for(int i=1;i<=n;++i) cin>>b[i];
        for(int i=1;i<=n;++i) cin>>c[i];
    
        int res=0;
        for(int p=n;p>=1;--p)
            res=add(res, calc(n/p, c[p]) );
        return res;
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        while(cin>>n)
            cout<<ans()<<"
    ";
        cout.flush();
        return 0;
    }
    

    【证明】

    矩阵推导:

    (T_{C(n, gcd(p,q)} )=T_{A(n, p)}T_{B(n, q)}) 可发现,每一个 (n) 之间都是独立的,故下文直接使用 (c_{gcd(p, q)},a_p,b_q) 等来简便表示

    (gcd) 的运算得:

    (egin{cases} c_0=a_0cdot b_0 \\ c_1=a_0cdot b_1=a_1cdot b_0=a_1cdot b_1=a_1cdot b_2=a_2cdot b_1 \\ c_2=a_0cdot b_2=a_2cdot b_0=a_2cdot b_2 end{cases})

    若要使得 (T_C) 可逆,则 (T_C) 矩阵满秩,故 (c_0,c_1,c_2) 不能同时为 (0)


    (a_0cdot b_2=a_2cdot b_2)(b_2cdot (a_0-a_2)),故 ((b_2=0)vee (a_0=a_2))

    (a_2cdot b_0=a_2cdot b_2)((a_2=0)vee (b_0=b_2))

    (c_2=a_0cdot b_2=a_2cdot b_0=a_2cdot b_2) 得:

    ((a_2=b_2=0)vee (b_0=b_2=0)vee (a_0=a_2=0)vee (a_0=a_2wedge b_0=b_2))

    由于 (a_0=0vee b_0=0)(c_0=c_1=c_2=0),不满足

    故仅解得 ((a_2=b_2=0)vee (a_0=a_2wedge b_0=b_2))


    (a_0cdot b_1=a_1cdot b_1=a_2cdot b_1)(a_0=a_1=a_2vee b_1=0)

    (a_1cdot b_0=a_1cdot b_1=a_1cdot b_2)(a_1=0vee b_0=b_1=b_2)

    故解得 ((a_0=a_1=a_2=0)vee (a_0=a_1=a_2wedge b_0=b_1=b_2)vee (b_1=a_1=0)vee(b_0=b_1=b_2=0))

    同理扣去 (a_0=0)(b_0=0) 的条件

    仅解得 ((a_0=a_1=a_2wedge b_0=b_1=b_2)vee(a_1=b_1=0))


    联立条件 (a_2=b_2=0)(a_0=a_1=a_2wedge b_0=b_1=b_2) 时,得到 (a_0=b_0=0) ,不合法

    联立条件 (a_2=b_2=0)(a_1=b_1=0) 时,得到 (a_1=a_2=0,b_1=b_2=0),代入得到 (c_1=c_2=0,c_0=a_0cdot b_0)

    (a_0=b_0=1) 得到一组解:(vec a=(1, 0, 0), vec b=(1, 0, 0), vec c=(1, 0, 0))

    联立条件 ((a_0=a_2wedge b_0=b_2))((a_0=a_1=a_2wedge b_0=b_1=b_2)) 时,得到 (c_0=c_1=c_2=a_0cdot b_0)

    (a_0=b_0=1) 得到一组解:(vec a=(1, 1, 1), vec b=(1, 1, 1), vec c=(1, 1, 1))

    联立条件 ((a_0=a_2wedge b_0=b_2))(a_1=b_1=0) 时,得到 (c_1=0, c_0=c_2=a_0cdot b_0)

    (a_0=b_0=1) 得到一组解:(vec a=(1, 0, 1), vec b=(1, 0, 1), vec c=(1, 0, 1))


    综上,可构造出矩阵 (T_A=left( egin{matrix} 1&0&0 \\ 1&1&1 \\ 1&0&1 end{matrix} ight), T_B=left( egin{matrix} 1&0&0 \\ 1&1&1 \\ 1&0&1 end{matrix} ight), T_C=left( egin{matrix} 1&0&0 \\ 1&1&1 \\ 1&0&1 end{matrix} ight))

    ((T_C|E)=left( egin{array}{ccc|ccc} 1&0&0& 1&0&0 \\ 1&1&1& 0&1&0 \\ 1&0&1& 0&0&1 end{array} ight) o left( egin{array}{ccc|ccc} 1&0&0& 1&0&0 \\ 0&1&0& 0&1&-1 \\ 0&0&1& -1&0&1 end{array} ight)=(Emid T_C^{-1}))

    得到 (T_C^{-1}=left( egin{matrix} 1&0&0 \\ 0&1&-1 \\ -1&0&1 end{matrix} ight))

  • 相关阅读:
    Lucas定理及其应用
    HDU 5044 TREE
    HDU 5033 Building
    Codeforces Round #238 (Div. 1)
    hdu 4878 ZCC loves words AC自动机+中国剩余定理+快速幂
    HDU 5015 233 Matrix
    HDU 5008 Boring String Problem
    ZOJ 3817 Chinese Knot
    使用AutoMapper
    多租户概念以及FreeLink多租户设计思想
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/15054115.html
Copyright © 2020-2023  润新知