HDU 6128 Inverse of sum(数论)——2017 Multi-University Training Contest

来源:互联网 发布:java 查看classpath 编辑:程序博客网 时间:2024/04/29 14:35

传送门

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 a1n which are less than p. HazelFan wants to know how many pairs i,j(1i<jn) are there, satisfying 1ai+aj1ai+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(1T5), denoting the number of test cases.
For each test case:
The first line contains two positive integers n,p(1n105,2p1018), and it is guaranteed that p is a prime number.
The second line contains n nonnegative integers a1...n(0ai<p).
 

Output
For each test case:
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个小于质数p的非负整数a1n,你想知道有多少对i,j(1i<jn),使得模p意义下1ai+aj1ai+1aj,即这两数的和的逆元等于它们逆元的和,注意零元没有逆元。1n105,2p1018

解题思路:

1ai+aj1ai+1aj

将式子进行通分得到:
(ai+aj)2=aiaj

将式子展开并移项,进行合并同类项得到:
a2i+aiaj+a2j0modp

将式子两边同时乘以 aiaj 得到:
a3ia3j0modp

推到这儿就会发现已经很好做了,就是用一个 map 统计一下每个数 x3modp 的个数,然后就是从x3modp 结果相同的数中选两个数(题目要求就是两个数)。
还需要注意的几个点:
1) 0没有逆元
2) 当 aiaj=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**/
阅读全文
0 0
原创粉丝点击