2021杭电多校第二场1010(找规律,快速乘)

2021杭电多校第二场1010(找规律,快速乘)

Problem - 6970 (hdu.edu.cn)

思路:

通过打表,可以得出获得的序列一定是一个长度为p-1的排列

令这个排列为\(\pi\),排列的第i个数为\(\pi(i)\),排列的逆序对数为\(n(\pi)\),计\(sgn(\pi)=(-1)^{n(\pi)}\)

很明显\(sgn(\pi)=\frac{\prod_{0<i<j\le p-1}\pi(i)-\pi(j)}{\prod_{0<i<j\le p-1}i-j}=\prod_{0<i<j\le p-1}\frac{\pi(i)-\pi(j)}{i-j}\)

由本题中的定义\(\pi(i)=ia\ (mod\ p)\)

\(\prod_{0<i<j\le p-1}\frac{\pi(i)-\pi(j)}{i-j}=\prod_{0<i<j\le p-1}\frac{ai-aj}{i-j}=a^{\frac{p(p-1)}{2}}\equiv a^{\frac{p}{2}}\ (mod\ p)\)

这里我个人认为按费马小定理化出来的结果是\(a^{\frac{p}{2}}\),但官方题解这里给了\(a^{\frac{p-1}{2}}\)(可能是为了凑二次剩余的形式看起来好看?),但由于题目保证p为一个奇素数,所以\(\frac{p}{2}=\frac{p-1}{2}\),对答案没有影响。

然后我们只需要计算\(a^{\frac{p}{2}}\ (mod\ p)\) 即可判断\(n(\pi)\)的奇偶

注意\(1\le a,p\le 1e18\)中间需要用到快速乘,但朴素的快速乘会T,题解这里貌似用到了什么黑科技

#include<bits/stdc++.h>
using namespace std;
long long mod;
long long mul(long long a,long long b)
{
	long long res=0;
	while(b)
	{
		if(b&1)
		{
			res=(res+a);
			if(res>=mod)res-=mod;
		}
		a=(a<<1);
		if(a>=mod)a-=mod;
		b>>=1;
	}
	return res;
}
inline long long Mul(long long x,long long y){
    long long tmp=(x*y-(long long)((long double)x/mod*y+1.0e-8)*mod);
    return (tmp+mod)%mod;
}
long long ksm(long long a,long long b)
{
	long long res=1;
	while(b)
	{
		if(b&1)res=Mul(res,a);
		a=Mul(a,a);
		b>>=1;
	}
	return res;
} 
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		long long a;
		scanf("%lld%lld",&a,&mod);
		if(ksm(a,(mod)/2)==1)puts("0");
		else puts("1");
	}
	return 0;
}
posted @ 2021-08-23 13:29  1427314831a  阅读(51)  评论(0编辑  收藏  举报