Inverse of sum
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 326 Accepted Submission(s): 112
Problem Description
There are
n
nonnegative integers a1…n which are less than
p
. HazelFan wants to know how many pairs i,j(1≤i<j≤n) are there, satisfying
1ai+aj≡1ai+1aj
when we calculate module
p
, which means the inverse element of their sum equals the sum of their inverse elements. Notice that zero element has no inverse element.
Input
The first line contains a positive integer T(1≤T≤5) , denoting the number of test cases.
For each test case:
The first line contains two positive integers n,p(1≤n≤105,2≤p≤1018) , and it is guaranteed that p is a prime number.
The second line containsn nonnegative integers
a1...n(0≤ai<p)
.
For each test case:
The first line contains two positive integers n,p(1≤n≤105,2≤p≤1018) , and it is guaranteed that p is a prime number.
The second line contains
Output
For each test case:
A single line contains a nonnegative integer, denoting the answer.
A single line contains a nonnegative integer, denoting the answer.
Sample Input
2
5 7
1 2 3 4 5
6 7
1 2 3 4 5 6
Sample Output
4
6
题目大意:
1009
有
n
个小于质数
解题思路:
1ai+aj≡1ai+1aj
将式子进行通分得到:
(ai+aj)2=ai∗aj
将式子展开并移项,进行合并同类项得到:
a2i+∗ai∗aj+a2j≡0modp
将式子两边同时乘以 ai−aj 得到:
a3i−a3j≡0modp
推到这儿就会发现已经很好做了,就是用一个 map 统计一下每个数 x3modp 的个数,然后就是从 x3modp 结果相同的数中选两个数(题目要求就是两个数)。
还需要注意的几个点:
1) 0没有逆元
2) 当 ai−aj=0 的时候不满足条件,需要特判 就用另一个 map 存一下相同的个数,然后减去其中对应的方案数就OK了
3) 当模数是 3 的时候 需要特殊判断,这个就不需要考虑两个数相同的情况了,因为 3 没有二次剩余
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5+5;
const double PI = acos(-1);
const double eps = 1e-8;
const LL MOD = 1e9+7;
inline int GCD(int a, int b){
if(b == 0) return a;
return GCD(b, a%b);
}
inline LL GCD(LL a, LL b){
if(b == 0) return a;
return GCD(b, a%b);
}
inline int LCM(int a, int b){
return a/GCD(b, a%b)*b;
}
inline LL LCM(LL a, LL b){
return a/GCD(b, a%b)*b;
}
namespace IO {
const int MX = 4e7; //1e7占用内存11000kb
char buf[MX]; int c, sz;
void begin() {
c = 0;
sz = fread(buf, 1, MX, stdin);
}
inline bool read(LL &t) {
while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;
if(c >= sz) return false;
bool flag = 0; if(buf[c] == '-') flag = 1, c++;
for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';
if(flag) t = -t;
return true;
}
}
LL Multi(LL a, LL b, LL p){
LL ans = 0;
while(b){
if(b & 1) ans = (ans + a) % p;
b>>=1;
a = (a + a) % p;
}
return ans;
}
LL Pow(LL a, LL b, LL p){
LL ans = 1;
while(b){
if(b & 1) ans = Multi(ans, a, p);
b>>=1;
a = Multi(a, a, p);
}
return ans;
}
void Exgcd(LL a, LL b, LL &x, LL &y){
if(b == 0){
x = 1;
y = 0;
return ;
}
LL x1, y1;
Exgcd(b, a%b, x1, y1);
x = y1;
y = x1 - (a/b)*y1;
}
map<LL, int>mp, mp1;
map<LL, int>::iterator it;
int main(){
//freopen("C:/Users/yaonie/Desktop/in.txt", "r", stdin);
//freopen("C:/Users/yaonie/Desktop/out.txt", "w", stdout);
IO::begin();
LL T; //scanf("%d", &T);
IO::read(T);
while(T--){
LL n; //scanf("%d", &n);
IO::read(n);
LL p, x; //scanf("%lld", &p);
IO::read(p);
mp.clear();
mp1.clear();
for(int i=0; i<n; i++){
//scanf("%lld",&x);
IO::read(x);
if(x == 0) continue;
mp1[x]++;
x = Pow(x, 3, p);
mp[x]++;
}
LL ans = 0;
for(it=mp.begin(); it!=mp.end(); it++){
LL tmp = (it->second);
tmp = tmp*(tmp-1)/2;
ans = ans + tmp;
}
if(p != 3)
for(it=mp1.begin(); it!=mp1.end(); it++){
LL tmp = (it->second);
tmp = tmp*(tmp-1)/2;
ans = ans - tmp;
}
printf("%lld\n",ans);
}
return 0;
}
/**
_ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
佛祖保佑 每次AC
**/