码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 6128-数论

时间:2017-08-16 00:04:50      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:ase   散列   ==   continue   return   ima   std   pre   time   

题意&官方题解

技术分享

没学过二次剩余……比赛的时候想到了下面的方法(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$

代码

 1 #include <map>
 2 #include <set>
 3 #include <queue>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <vector>
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <cstdlib>
10 #include <iostream>
11 #include <algorithm>
12 #define MAX     1000007
13 #define MAXN      10007
14 #define MAXM      20007
15 #define INF  0x3f3f3f3f
16 #define NINF 0xc0c0c0c0
17 #define MOD  1000000007
18 using namespace std;
19 typedef unsigned long long LL;
20 
21 
22 LL a[MAX],p;
23 int n;
24 LL Multi(LL a,LL b,LL m){
25     LL ret = 0;  
26     while(b){  
27         if(b&1) ret=(ret+a)%m;  
28         b>>= 1;  
29         a=(a<<1)%m;  
30     }  
31     return ret;  
32 }  
33 LL ac(LL x){
35     return (x-1)*x/2;
36 }
37 map<LL,map<LL,LL> >M;
38 map<LL,LL>sum;
39 LL x;
40 int main(){
43     int cas;
44     scanf("%d",&cas);
45     while(cas--){
46         M.clear();
47         sum.clear();
48         scanf("%d%lld",&n,&p);
49         if(p==3){
50             int xx,one=0,two=0;
51             for(int i=0;i<n;i++){
52                 scanf("%d",&xx);
53                 if(xx==1)one++;
54                 else if(xx==2)two++;
55             }
56             printf("%d\n",ac(one)+ac(two));
57             continue;
58         }
59         LL num=0;
60         for(int i=0;i<n;i++){
61             scanf("%lld",&x);
62             x%=p;
63             if(x==0)continue;
64             LL y=Multi(x,x,p);
65             y=Multi(x,y,p);
66             M[y][x]++;
67             sum[y]++;
68             num++;
69         }
70         LL ans=0;
71         map<LL,map<LL,LL> >::iterator it=M.begin();
72         for(;it!=M.end();it++){
73             //printf("%lld\n", it->first);
74             if(it->first==0)continue;
75             ans+=ac(sum[it->first]);
76             //printf("%lld %lld\n",sum[it->first],ans);
77             map<LL,LL>::iterator tt=it->second.begin();
78             for(;tt!=it->second.end();tt++){
79                 ans-=ac(tt->second);
80             }
81         }
82         printf("%lld\n",ans);
83     }
84     return 0;
85 }

 

HDU 6128-数论

标签:ase   散列   ==   continue   return   ima   std   pre   time   

原文地址:http://www.cnblogs.com/shuiming/p/7368053.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!