CF1188B/1189E [count pairs]

题目大概意思就是

有几对 \(i\) , \(j\) 满足 \((a_i+a_j)\) * \((a_i^2 + a_j^2)\) % \(p\) = \(k\) % \(p\)

暴力的时间复杂度显然是 \(θ(N^2)\) 的 , \(2 <= N <= 300000\) 显然会 T 掉 而 CF T 掉是没有部分分的

好我们看 根据初中的数学知识
\[(a+b)(a-b) = a^2 - b^2\]

当我们看到 \((a_i+a_j)\) 肯定会第一个想到\((a_i-a_j)\)

所以两边同乘 \((a_i-a_j)\) , 然后根据柿子
可得
\[(a_i^2 + a_j^2)(a_i^2 - a_j^2)\%p = k(a_i-a_j)\%p\]

那么再根据柿子
\[(a+b)(a-b) = a^2 - b^2\]
不难再次合并
可得
\[(a_i^4 - a_j^4) = k *a_i - k * a_j\]

然后移项

\[a_i^4 - a_i *k= a_j^4 - a_j *k\]

如何\(\theta(N)\) 算出答案的值呢?

int ans = 0 ;
    for(register int i=1;i<=n;i++) {
        ans += mp[f[i]] ;
        ++ mp[f[i]] ;
    }

记得多取模%%% + LL

#include <bits/stdc++.h>
#define rep(i,j,n) for(register int i=j;i<=n;i++)
#define Rep(i,j,n) for(register int i=j;i>=n;i--)
#define low(x) x&(-x)
using namespace std ;
typedef long long LL ;
const int inf = INT_MAX >> 1 ;
inline LL read() {
    LL res(0) , f(1) ;
    register char c ;
#define gc c = getchar()
    while(isspace(gc)) ;
    c == '-' ? f = - 1 , gc : 0 ;
    while(res = (res << 1) + (res << 3) + (c & 15) , isdigit(gc)) ;
    return res * f ;
#undef gc
}
 
#define int long long
int n , p , k ;
int a[300000 + 5] ;
int f[300000 + 5] ;
 
map < int , int > mp ;
inline void Ot() {
    n = read() , p = read() , k = read() ;
    for(register int i=1; i<=n; i++) a[i] = read() ;
    for(register int i=1; i<=n; i++) {
        f[i] = (a[i] * a[i]) % p * a[i] % p * a[i] % p - a[i] * k % p ;
        f[i] %= p ;
        if(f[i] < 0) f[i] += p ;
    }
    int ans = 0 ;
    for(register int i=1;i<=n;i++) {
        ans += mp[f[i]] ;
        ++ mp[f[i]] ;
    }
    cout << ans << endl ;
    return ;
}
signed main() {
//  freopen("test.in","r",stdin) ;
    return Ot() , 0 ;
}

转载于:https://www.cnblogs.com/qf-breeze/p/11141522.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值