• [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
    ", res);
    	return 0;
    }
    
  • 相关阅读:
    C# 连接 Oracle 的几种方式
    Mac电脑卸载软件后删除残余图标
    文件监视器数量达到系统限制
    Android实现伸缩弹力分布菜单效果
    XMPP协议实现原理介绍
    Android开发之日历控件实现
    OpenGL开发之旅基础知识介绍
    Android in Mono开发初体验之DataBase
    JAVA实现随机无重复数字功能
    Android实现宫格图片连续滑动效果
  • 原文地址:https://www.cnblogs.com/linzhengmin/p/11142652.html
Copyright © 2020-2023  润新知