传送门:https://ac.nowcoder.com/acm/contest/15332/B
年轻人第一道fft题,特此纪念。
#if __has_include(<bits/stdc++.h>)
#include<bits/stdc++.h>
#endif
#include<iostream>
#include<bitset>
#include<map>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<sstream>
#include<stack>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pll;
template<class T,class U>
ostream& operator<<(ostream& os,const pair<T,U>& p){os<<p.first<<" "<<p.second;return os;}
#define debug(x) cerr<<#x<<":"<<x<<endl
#define debug2(x,y) cerr<<#x<<":"<<x<<" "<<#y<<":"<<y<<endl
#define debug3(x,y,z) cerr<<#x<<":"<<x<<" "<<#y<<":"<<y<<" "<<#z<<":"<<z<<endl
#define debuga(a) for(int i=0;i<a.size();++i) debug2(i,a[i]);
#define debugar(a,b) for(int i=0;i<b;++i) debug2(i,a[i]);
const ll N=3e5;
int cnt=0,prime[N],visit[N];
void pre(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
for(int i=2;i<N;++i){
if(!visit[i]) prime[cnt++]=i;
for(int j=0;i*prime[j]<N;++j){
visit[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
const ld PI=acos(-1);
struct C{
ld x,y;
C(ld a=0,ld b=0):x(a),y(b){}
C& operator=(const C& rhs){
x=rhs.x;
y=rhs.y;
return *this;
}
C operator+(const C& rhs)const{
return C(x+rhs.x,y+rhs.y);
}
C& operator+=(const C& rhs){
return *this=(operator+(rhs));
}
C operator-(const C& rhs)const{
return C(x-rhs.x,y-rhs.y);
}
C& operator-=(const C& rhs){
return *this=(operator-(rhs));
}
C operator*(const C& rhs)const{
return C(x*rhs.x-y*rhs.y,x*rhs.y+y*rhs.x);
}
C& operator*=(const C& rhs){
return *this=(operator*(rhs));
}
};
int rev[N];
void fft(vector<C>& a,ll n,ll sign){
for(int i=0;i<n;++i) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int mid=1;mid<n;mid<<=1){
C wn(cos(PI/mid),sign*sin(PI/mid));
for(int i=0;i<n;i+=mid<<1){
C w(1);
for(int j=0;j<mid;++j,w*=wn){
C x=a[i+j],y=w*a[i+j+mid];
a[i+j]=x+y;
a[i+j+mid]=x-y;
}
}
}
}
int main(){
pre();
ll T;
cin>>T;
while(T--){
vector<C> a(N);
memset(rev,0,sizeof rev);
ll n,m,t,MAXV=-1,MAXW=-1,l=-1,mi=1;
cin>>n>>m;
for(int i=0;i<n;++i){
cin>>t;
++a[t].x;
MAXV=max(MAXV,t);
}
for(int i=0;i<m;++i){
cin>>t;
++a[t].y;
MAXW=max(MAXW,t);
}
while(mi<(MAXV+MAXW)) mi<<=1,++l;
for(int i=0;i<=mi;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<l);
fft(a,mi,1);
for(int i=0;i<=mi;++i) a[i]*=a[i];
fft(a,mi,-1);
ll res=0;
for(int i=0;prime[i]<=MAXV+MAXW;++i) res+=(ll)(a[prime[i]].y/(mi<<1)+0.5);
cout<<res<<endl;
}
}