1. 程式人生 > >Newcoder 148 E.Rikka with Equation(數論+莫比烏斯反演)

Newcoder 148 E.Rikka with Equation(數論+莫比烏斯反演)

Description

對於一個長度為nn的正整數序列AA和一個正整數mm,定義f(A,m)f(A,m)為滿足同餘方程 i=1nAixi0(modm) \sum\limits_{i=1}^n A_ix_i\equiv 0(mod\ m) 的向量xi[0,m]x_i\in [0,m]的個數。現在給出一個長度為nn的序列BB和一個正整數MM,記BBN=2n1N=2^n-1個非空子序列為A1,...,ANA_1,...,A_N,對於每個m[1,M]m\in [1,M]

,求i=1Nf(Ai,m)\sum\limits_{i=1}^Nf(A_i,m)

Input

第一行一整數TT表示用例組數,每組用例首先輸入兩個整數n,Mn,M,之後輸入nn個正整數BiB_i

(1T3,1n,M105,1Bi105)(1\le T\le 3,1\le n,M\le 10^5,1\le B_i\le 10^5)

Output

wm=i=1Nf(Ai,m)mod998244353w_m=\sum\limits_{i=1}^Nf(A_i,m)\ mod\ 998244353

=i=1Nf(Ai,m)mod998244353,輸出i=1Mwi\oplus_{i=1}^Mw_i,其中\oplus為異或操作

Sample Input

2 5 5 1 2 3 4 5 10 10 1 2 3 4 5 6 7 8 9 10

Sample Output

1079 933958261

Solution

首先考慮求f(A,m)f(A,m),任意固定x1,...,xn1x_1,...,x_{n-1},假設Aixiyi(modm)A_ix_i\equiv y_i(mod\ m),顯然存在kk

使得 y1+...+yn1=kgcd(A1,A2,...,An1,m) y_1+...+y_{n-1}=k\cdot gcd(A_1,A_2,...,A_{n-1},m) 原方程成立等價於求滿足 kgcd(A1,...,An1,m)+Anxn0(modm) k\cdot gcd(A_1,...,A_{n-1},m)+A_n\cdot x_n\equiv 0(mod\ m) xnx_n個數,顯然有gcd(gcd(A1,m),...,gcd(An,m),m)gcd(gcd(A_1,m),...,gcd(A_n,m),m)個解,也即gcd(A,m)gcd(A,m)個解,故 f(A,m)=mn1gcd(A,m) f(A,m)=m^{n-1}\cdot gcd(A,m) 假設BB序列中為dd倍數的數字有ndn_d個,記f(d)f(d)BB的子序列中滿足gcd(A,m)=dgcd(A,m)=dmA1m^{|A|-1}求和,F(d)F(d)BB的子序列中滿足dgcd(A,m)d|gcd(A,m)mA1m^{|A|-1}求和,則有 F(d)=dif(i),F(d)=i=1ndCndimi1=(m+1)nd1m F(d)=\sum\limits_{d|i}f(i),F(d)=\sum\limits_{i=1}^{n_d}C_{n_d}^i\cdot m^{i-1}=\frac{(m+1)^{n_d}-1}{m} 由莫比烏斯反演 f(d)=diμ(id)F(i) f(d)=\sum\limits_{d|i}\mu(\frac{i}{d})F(i) 故有 wm=i=1Nf(Ai,m)=dmf(d)d=imF(i)didμ(id)=dmφ(d)F(d) w_m=\sum\limits_{i=1}^Nf(A_i,m)=\sum\limits_{d|m}f(d)\cdot d=\sum\limits_{i|m}F(i)\sum\limits_{d|i}d\cdot \mu(\frac{i}{d})=\sum\limits_{d|m}\varphi(d)\cdot F(d) 預處理φ,F\varphi,F即可O(mlogm)O(mlogm)得到w1,...,wmw_1,...,w_m

Code

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
#define maxn 100005
int euler[maxn],prime[maxn],res;
void get_euler(int n=1e5)
{
    euler[1]=1;
    res=0;
    for(int i=2;i<=n;i++)
    {
        if(!euler[i])euler[i]=i-1,prime[res++]=i;
        for(int j=0;j<res&&prime[j]*i<=n;j++)
        {
            if(i%prime[j]) euler[prime[j]*i]=euler[i]*(prime[j]-1);
            else
            {
                euler[prime[j]*i]=euler[i]*prime[j];
                break;
            }
        }
    }
}
#define mod 998244353
int mul(int x,int y)
{
	ll z=1ll*x*y;
	return z-z/mod*mod;
}
int add(int x,int y)
{
	x+=y;
	if(x>=mod)x-=mod;
	return x;
}
int Pow(int x,ll y)
{
	int ans=1;
	while(y)
	{
		if(y&1)ans=mul(ans,x);
		x=mul(x,x);
		y>>=1;
	}
	return ans;
}
int T,n,m,b[maxn],a[maxn];
void deal(int x)
{
	for(int i=1;i*i<=x;i++)
		if(x%i==0)
		{
			a[i]++;
			if(i*i!=x)a[x/i]++;
		}
}
int inv[maxn],fact[maxn],sum[maxn],f[maxn];
void init(int n=1e5)
{
	inv[1]=1;
	for(int i=2;i<=n;i++)inv[i]=mul(mod-mod/i,inv[mod%i]);
	sum[0]=1;
	for(int i=