HDU 6128-数论
题意&官方题解

没学过二次剩余……比赛的时候想到了下面的方法(1591ms)。但是没特判$p=3$的情况,愉快的WA
……
分析
根据式子我们可以推到$a^2+ab+b^2=0 (mod\ p)$
当$a=b$的时候
$3a^2=0(mod\ p)$
当$p=3$的时候有解$a=1\ or\ a=2$
当$p \neq 3$的时候无解
当$a \neq b$的时候
不妨两边乘$(a-b)$得到$a^3-b^3=0 (mod\ p)$
就得到了散列函数$f(x)=x^3mod\;p$
结论也就出现了
$\begin{cases}a=b=1\ or\ a=b=2,p=3 \\f(a)=f(b),p \neq 3 \end{cases}$
注意数据范围,最大有$10^{18}$,立方的时候需要快速乘
具体分析
样例1
6 3
0 1 1 2 2 2
- 1 1 2 2 2 逆元
- 1 1 2 2 2 $f(x)$
4
解集为$\{(1,1),(2,2),(2,2),(2,2)\}$
样例1
5 7
1 2 3 4 5 6
1 4 5 2 3 6 逆元
1 1 6 1 6 6 $f(x)$
6
解集为$\{(1,2),(1,4),(2,4),(3,5),(3,6),(5,6)\}$,都满足$f(a)=f(b),a \neq b$
样例3
5 7
1 1 2 2 4
1 1 4 4 2
1 1 1 1 1 $f(x)$
8
解集为$\{(1,2),(1,2),(1,4),(1,2),(1,2),(1,4),(2,4),(2,4)\}$,都满足$f(a)=f(b),a \neq b$
代码
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define MAX 1000007
#define MAXN 10007
#define MAXM 20007
#define INF 0x3f3f3f3f
#define NINF 0xc0c0c0c0
#define MOD 1000000007
using namespace std;
typedef unsigned long long LL;
LL a[MAX],p;
int n;
LL Multi(LL a,LL b,LL m){
LL ret = 0;
while(b){
if(b&1) ret=(ret+a)%m;
b>>= 1;
a=(a<<1)%m;
}
return ret;
}
LL ac(LL x){
return (x-1)*x/2;
}
map<LL,map<LL,LL> >M;
map<LL,LL>sum;
LL x;
int main(){
int cas;
scanf("%d",&cas);
while(cas--){
M.clear();
sum.clear();
scanf("%d%lld",&n,&p);
if(p==3){
int xx,one=0,two=0;
for(int i=0;i<n;i++){
scanf("%d",&xx);
if(xx==1)one++;
else if(xx==2)two++;
}
printf("%d\n",ac(one)+ac(two));
continue;
}
LL num=0;
for(int i=0;i<n;i++){
scanf("%lld",&x);
x%=p;
if(x==0)continue;
LL y=Multi(x,x,p);
y=Multi(x,y,p);
M[y][x]++;
sum[y]++;
num++;
}
LL ans=0;
map<LL,map<LL,LL> >::iterator it=M.begin();
for(;it!=M.end();it++){
//printf("%lld\n", it->first);
if(it->first==0)continue;
ans+=ac(sum[it->first]);
//printf("%lld %lld\n",sum[it->first],ans);
map<LL,LL>::iterator tt=it->second.begin();
for(;tt!=it->second.end();tt++){
ans-=ac(tt->second);
}
}
printf("%lld\n",ans);
}
return 0;
}

浙公网安备 33010602011771号