[SDOI2015]序列统计

[SDOI2015]序列统计

题意:你有一个长度为n的序列,每个位置上的数都是小于M的非负整数,且每个数必须属于给定集合S,问有多少个数列使得所有数的乘积膜M为x

解析:

我们显然发现该问题可以分治,而且M的范围比较小所以我们可以根据算出长度为n,乘积在膜意义下为s的方案数,然后就可以得到2n的答案

但是由于在计算过程中是膜意义下的(下标),所以一旦算的话还是要M^2枚举,但是我们发现我们还没有用到M为质数这个限制

我们现在遇到的问题是什么?就是下标是乘,这个很麻烦,怎么把下标转化到指数上面去(用更高级的运算符来压他)

原根!!!质数一定有原根,由于原根的性质,我们可以映射到原根的指数上,这样问题就解决了(具体不细讲)

// luogu-judger-enable-o2
#include
#define ll long long
using namespace std;
const int N=1e5+10;
const ll mod=1004535809;
ll a[N],b[N],g[N],f[N];
int n,m,x,len,gg,lens,k,la,pu[N],rev[N];
ll ksm(ll x,ll y,ll mod)
{
	ll ans=1;
	for (;y;y>>=1,x=(x*x)%mod) if (y&1) ans=(ans*x)%mod;
	return ans;	
}
int fi(int x)
{
	for (int i=2;i>1]>>1)|((i&1)<<(k-1));
	solve(n);
	printf("%lld\n",g[pu[x]]);	
}

 

你可能感兴趣的:(省选)