根据题意我们有:\(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;
}