其他分享
首页 > 其他分享> > Codeforces 1188B - Count Pairs(思维题)

Codeforces 1188B - Count Pairs(思维题)

作者:互联网

Codeforces 题面传送门 & 洛谷题面传送门

虽说是一个 D1B,但还是想了我足足 20min,所以还是写篇题解罢(

首先注意到这个式子里涉及两个参数,如果我们选择固定一个并动态维护另一个的决策,则相当于我们要求方程 \(ax^3+bx^2+cx+d\equiv k\pmod{p}\) 的根,而这是很难维护的,因此这个思路行不通。考虑 \((x+y)(x^2+y^2)\) 的性质,我们考虑在前面添上一项 \((x-y)\),根据初中数学 \((x-y)(x+y)(x^2+y^2)=x^4-y^4\),因此 \((x+y)(x^2+y^2)=\dfrac{x^4-y^4}{x-y}\),因此我们即需求 \(\dfrac{a_i^4-a_j^4}{a_i-a_j}\equiv k\pmod{p}\) 的 \((i,j)\) 个数,两边同乘 \((a_i-a_j)\) 再移个项可得 \(a_i^4-ka_i\equiv a_j^4-ka_j\pmod{p}\),map 维护即可,由于 \(a_i\ne a_j\),所以左边的分式肯定有意义。

虽说是个 *2300,但还是让我学到了许多,稍微总结一下吧:

const int MAXN=3e5;
int n,k,p,a[MAXN+5];map<int,int> t;
int calc(int x){return (1ll*x*x%p*x%p*x%p-1ll*k*x%p+p)%p;}
int main(){
	scanf("%d%d%d",&n,&p,&k);ll res=0;
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++) res+=t[calc(a[i])],t[calc(a[i])]++;
	printf("%lld\n",res);
	return 0;
}

标签:Count,1188B,Pairs,int,dfrac,d%,x%,pmod,equiv
来源: https://www.cnblogs.com/ET2006/p/Codeforces-1188B.html