您的位置:首页 > 其它

牛客网多校10 E - Rikka with Equation

2018-08-20 01:45 162 查看

https://www.nowcoder.com/acm/contest/148/E

想了很久才想出来

其实也不算很难,关键是给定A数组,怎么去求解的个数

答案如下:

就是如果a和m互素,那么a一定存在关于m的逆元,这样n-1个数随便取,最后一个数有唯一的取法。

如果gcd>1,那么n-1个数随便取,最后一个数有gcd种取法。

有n个数,2^n-1个非空子集,我们假设gcd全为1,求所有非空子集的答案之和,结果为:

然后容斥原理一下就可以了

 

代码:

[code]#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=998244353;
int n,m,t;
int a[100005];
ll inv_m;
ll p[5005];

void read(int &x){
char ch = getchar();x = 0;
for (; ch < '0' || ch > '9'; ch = getchar());
for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
}

void push(int x)
{
for (int i=1;i*i<=x;i++)
{
if (x%i==0)
{
if (i*i==x) a[i]++;
else {a[i]++;a[x/i]++;}
}
}
}

ll qk_pow(ll a,int b)
{
ll res = 1;
while(b)
{
if(b & 1)
{
res = res * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return res;
}

long long inv(long long a,long long m)
{
if(a == 1)return 1;
return inv(m%a,m)*(m-m/a)%m;
}

ll F(int n,int m)
{
return (qk_pow(m+1,n)-1)*inv_m%mod;
}

int main()
{
read(t);
while (t--)
{
read(n);
read(m);
memset(a,0,sizeof(a));
for (int i=1;i<=n;i++)
{
int x;
read(x);
push(x);
}
ll ans=(qk_pow(2,n)-1+mod)%mod;
for (int i=2;i<=m;i++)
{
inv_m=inv(i,mod);
ll x=0;
vector<int> v;
for (int j=1;j*j<=i;j++)
{
if (i%j==0)
{
if (j*j==i) v.push_back(j);
else {v.push_back(j);v.push_back(i/j);}
}
}
sort(v.begin(),v.end());
for (int j=0;j<v.size();j++)
{
p[j]=F(a[v[j]],i);
}
for (int j=(int)v.size()-1;j>=0;j--)
{
for (int k=j+1;k<v.size();k++)
{
if (v[k]%v[j]==0)
{
p[j]=(p[j]-p[k]+mod)%mod;
}
}
}
for (int j=0;j<v.size();j++)
{
x=(x+p[j]*v[j])%mod;
}
ans^=x;
}
printf("%lld\n",ans);
}
return 0;
}

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: