题解 HDU 6966 I love sequences
【大意】
给定 \(n\) 和三个下标从 \(1\) 开始,长度为 \(n\) 的数列 \(a, b, c\)
对于整数 \(p\), 我们构造数列 \(\displaystyle d_{p,k}=\sum_{i\otimes j=k}a_ib_j(1\leq i, j\leq{n\over p})\)
其中,位运算 \(i\otimes j\) 表示 \(i\) 与 \(j\) 在三进制意义下按位取 \(\gcd\),即 \(k_t=\gcd(i_t, j_t)\)
现要求求出 \(\displaystyle \sum_{p=1}^n\sum_{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( \begin{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} \right)\) 为可逆矩阵即可
具体推导过程见后文,这里直接给出一组解: \(T_A=T_B=T_C=\left( \begin{matrix} 1&0&0 \\\\ 1&1&1 \\\\ 1&0&1 \end{matrix} \right)\) ,逆矩阵 \(T_C^{-1}=\left( \begin{matrix} 1&0&0 \\\\ 0&1&-1 \\\\ -1&0&1 \end{matrix} \right)\)
由此,对 \(a,b\) 的前 \({n\over p}\) 项提取出来,进行 FWT 变换为 \(T_Aa,T_Bb\) 后直接点积,求出 \(T_Cd\)
再由 \(d=T_C^{-1}\cdot T_Cd\) 进行 UFWT 求出 \(d\) 数列
之后由秦九韶定理,可以 \(O({n\over p})\) 直接跑出第二个求和符号内的结果
总时间复杂度为 \(\displaystyle T(n)=\sum_{p=1}^n[O({n\over p}\log{n\over p})+O({n\over p})]=O(n\log^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()<<"\n";
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\) 的运算得:
\(\begin{cases} c_0=a_0\cdot b_0 \\\\ c_1=a_0\cdot b_1=a_1\cdot b_0=a_1\cdot b_1=a_1\cdot b_2=a_2\cdot b_1 \\\\ c_2=a_0\cdot b_2=a_2\cdot b_0=a_2\cdot b_2 \end{cases}\)
若要使得 \(T_C\) 可逆,则 \(T_C\) 矩阵满秩,故 \(c_0,c_1,c_2\) 不能同时为 \(0\)
由 \(a_0\cdot b_2=a_2\cdot b_2\) 得 \(b_2\cdot (a_0-a_2)\),故 \((b_2=0)\vee (a_0=a_2)\)
由 \(a_2\cdot b_0=a_2\cdot b_2\) 得 \((a_2=0)\vee (b_0=b_2)\)
故 \(c_2=a_0\cdot b_2=a_2\cdot b_0=a_2\cdot b_2\) 得:
\((a_2=b_2=0)\vee (b_0=b_2=0)\vee (a_0=a_2=0)\vee (a_0=a_2\wedge b_0=b_2)\)
由于 \(a_0=0\vee b_0=0\) 时 \(c_0=c_1=c_2=0\),不满足
故仅解得 \((a_2=b_2=0)\vee (a_0=a_2\wedge b_0=b_2)\)
由 \(a_0\cdot b_1=a_1\cdot b_1=a_2\cdot b_1\) 得 \(a_0=a_1=a_2\vee b_1=0\)
由 \(a_1\cdot b_0=a_1\cdot b_1=a_1\cdot b_2\) 得 \(a_1=0\vee b_0=b_1=b_2\)
故解得 \((a_0=a_1=a_2=0)\vee (a_0=a_1=a_2\wedge 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_2\wedge b_0=b_1=b_2)\vee(a_1=b_1=0)\)
联立条件 \(a_2=b_2=0\) 与 \(a_0=a_1=a_2\wedge 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_0\cdot 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_2\wedge b_0=b_2)\) 与 \((a_0=a_1=a_2\wedge b_0=b_1=b_2)\) 时,得到 \(c_0=c_1=c_2=a_0\cdot 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_2\wedge b_0=b_2)\) 与 \(a_1=b_1=0\) 时,得到 \(c_1=0, c_0=c_2=a_0\cdot 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( \begin{matrix} 1&0&0 \\\\ 1&1&1 \\\\ 1&0&1 \end{matrix} \right), T_B=\left( \begin{matrix} 1&0&0 \\\\ 1&1&1 \\\\ 1&0&1 \end{matrix} \right), T_C=\left( \begin{matrix} 1&0&0 \\\\ 1&1&1 \\\\ 1&0&1 \end{matrix} \right)\)
由 \((T_C|E)=\left( \begin{array}{ccc|ccc} 1&0&0& 1&0&0 \\\\ 1&1&1& 0&1&0 \\\\ 1&0&1& 0&0&1 \end{array} \right)\to \left( \begin{array}{ccc|ccc} 1&0&0& 1&0&0 \\\\ 0&1&0& 0&1&-1 \\\\ 0&0&1& -1&0&1 \end{array} \right)=(E\mid T_C^{-1})\)
得到 \(T_C^{-1}=\left( \begin{matrix} 1&0&0 \\\\ 0&1&-1 \\\\ -1&0&1 \end{matrix} \right)\)