[CF1188B]Count Pairs 题解

Posted linzhengmin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1188B]Count Pairs 题解相关的知识,希望对你有一定的参考价值。

前言

这道题目是道好题。
第一次div-2进前100,我太弱了。

题解

公式推导

我们观察这个式子。
\[(a_i+a_j)(a_i^2+a_j^2)\equiv k \mod p\]
感觉少了点什么,我们想到两边同时乘一个\((a_i-a_j)\)
于是它变成了:
\[(a_i^2-a_j^2)(a_i^2+a_j^2) \equiv k(a_i-a_j) \mod p\]
也就是:
\[a_i^4-a_j^4 \equiv k(a_i-a_j) \mod p\]
\(k\)乘进去变成:
\[a_i^4-a_j^4 \equiv ka_i-ka_j \mod p\]
变换一下就是
\[a_i^4-ka_i \equiv a_j^4-ka_j \mod p\]
公式到这里就推完了

代码实现

实现很简单,根据上面的的公式,由于k是确定的,我们对于所有的\(a_i\)\((a_i^4-ka_i)\)取模之后放入一个STL map中,然后我们就可以计算有多少数跟它相同了。

复杂度

鉴于STL map的复杂度,时间复杂度为\(\Theta(nlog_2n)\)

代码

#include <cstdio>
#include <map>
 
using namespace std;
 
long long read()
    long long x = 0; int zf = 1; char ch = ' ';
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') zf = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;

 
map<long long, long long> mp;
 
int main() 
    long long n = read(), p = read(), k = read();
    long long res = 0;
    for (int i = 1; i <= n; ++i)
        long long x = read();
        long long tmp = ((((((x * x) % p * x) % p * x) % p - k * x) % p) % p + p) % p ;
        if (mp.count(tmp) == true)
            res += mp[tmp];
        ++mp[tmp];
    
    printf("%I64d\n", res);
    return 0;

以上是关于[CF1188B]Count Pairs 题解的主要内容,如果未能解决你的问题,请参考以下文章

题解CF#236(Div. 1) D-Beautiful Pairs of Numbers

[CF1486F]Pairs of Paths

[bzoj1807] [Ioi2007]Pairs 彼此能听得见的动物对数

CF1512D Corrupted Array 题解

CF398B题解

CF1051G 题解