CF1857F Sum and Product

发布时间 2023-10-07 21:39:14作者: LHLeisus

根据题意我们有:\(b=a_i+a_j\)\(c=a_i\times a_j\)

可以发现 \(a_i\)\(a_j\) 是一元二次方程 \(x^2-bx+c=0\) 的根。

那么就可以根据求根公式 \(x=\dfrac{-b\pm \sqrt{b^2-4ac}}{2a}\) 来求出 \(a_i\)\(a_j\) 的值,再将它们的数量相乘即为答案。需要注意的是 \(b^2-4ac<0\)\(=0\) 的情况需要处理,前者无解,后者有两个相等的根。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<utility>
#include<vector>
#include<queue>
#include<bitset>
#include<map>
#define FOR(i,a,b) for(register int i=a;i<=b;i++)
#define ROF(i,a,b) for(register int i=a;i>=b;i--)
#define mp(a,b) make_pair(a,b)
#define pll pair<long long,long long>
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int N=1e5+5;
const int INF=0x3f3f3f3f;
int n,m,k;
map<ll,int>mapi;
ll calc(ll b,ll c){
	ll a1,a2;
	ll delta=b*b-4*c;
	if(delta<0){
		return 0;
	}
	a1=(b-sqrt(delta))/2;
	a2=(b+sqrt(delta))/2;
	if(a1+a2!=b||a1*a2!=c) return 0;
	if(delta==0){
		return (ll)mapi[a1]*(mapi[a1]-1)/2;
	}
	return (ll)mapi[a1]*mapi[a2];
}
vector<ll>vec;
int main()
{
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		mapi.clear();
		vec.clear();
		FOR(i,1,n){
			ll t;
			scanf("%lld",&t);
			mapi[t]++;
		}
		scanf("%d",&k);
		while(k--){
			ll x,y;
			scanf("%lld%lld",&x,&y);
			vec.push_back(calc(x,y));
		}
		for(int i=0;i<vec.size();i++) printf("%lld ",vec[i]);
		puts("");
	}
	return 0;
}