Newcoder 148 E.Rikka with Equation(數論+莫比烏斯反演)
阿新 • • 發佈:2018-12-11
Description
對於一個長度為的正整數序列和一個正整數,定義為滿足同餘方程 的向量的個數。現在給出一個長度為的序列和一個正整數,記的個非空子序列為,對於每個,求
Input
第一行一整數表示用例組數,每組用例首先輸入兩個整數,之後輸入個正整數
Output
令,輸出,其中為異或操作
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
首先考慮求,任意固定,假設,顯然存在使得 原方程成立等價於求滿足 的個數,顯然有個解,也即個解,故 假設序列中為倍數的數字有個,記為的子序列中滿足的求和,為的子序列中滿足的求和,則有 由莫比烏斯反演 故有 預處理即可得到
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=