Problem:
F: MOD Rush

問題

長さ N の正の整数列 A と、長さ M の正の整数列 B が与えられます。

すべての (i, j) (1 \leq i \leq N, 1 \leq j \leq M) について、A_i を B_j で割ったあまりを求め、それらの和を出力してください。

入力形式

N M
A_1 A_2 ... A_N
B_1 B_2 ... B_M

制約

1 \leq N, M \leq 2 \times 10^5

1 \leq A_i, B_i \leq 2 \times 10^5

入力はすべて整数で与えられる

出力形式

答えを 1 行に出力してください。最後に改行してください。

入力例 1

3 3
5 1 6
2 3 4

出力例 1

9

数列 A の 1 番目の要素を、数列 B の各要素で割ったあまりを考えます。5 を 2 で割るとあまりは 1、3 で割るとあまりは 2、4 で割るとあまりは 1 です。

同様に 2 番目の要素についても考えると、あまりはそれぞれ 1, 1, 1 です。

3 番目の要素についても考えると、あまりはそれぞれ 0, 0, 2 です。

あまりを合計すると 1 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 2 = 9 となるので、9 を出力します。

入力例 2

2 4
2 7
3 3 4 4

出力例 2

16

数列内には同じ値が複数含まれていることがありますが、それぞれの要素に対してあまりを計算して和を求めます。

入力例 3

3 1
12 15 21
3

出力例 3

0

Solution in C (judge verdict: Accepted)

#include<stdio.h>
#define ll long long
#define rep(i,l,r)for(ll i=(l);i<(r);i++)

typedef struct atai{ll nxt,n,c;}atai;
atai x[200010];

//*
//プラキュー（二分ヒープ）（最低限バージョン）
//int PQhikaku(int i,int j);//jの方が優先度が高いならtrueを返す
int PQhikaku(ll*heap,int i,int j){return x[heap[i]].nxt>x[heap[j]].nxt;}
void heap_utod(ll*heap,int n){
	if(2*n>heap[0])return;
	int rflag=(2*n+1<=heap[0])&&(PQhikaku(heap,2*n,2*n+1));
	if(PQhikaku(heap,n,2*n+rflag)){
		ll temp=heap[2*n+rflag];
		heap[2*n+rflag]=heap[n];
		heap[n]=temp;
		heap_utod(heap,2*n+rflag);
	}
}
void heap_dtou(ll*heap,int n){
	if(n==1||PQhikaku(heap,n,n/2))return;
	ll temp=heap[n];
	heap[n]=heap[n/2];
	heap[n/2]=temp;
	heap_dtou(heap,n/2);
}
ll PQpop(ll*heap){
	ll rr=heap[1];
	heap[1]=heap[heap[0]--];
	heap_utod(heap,1);
	return rr;
}
void PQpush(ll*heap,ll n){
	heap[++heap[0]]=n;
	heap_dtou(heap,heap[0]);
}
//*/

ll a[200010];
ll b[200010];
ll h[200010];
int main(){
	ll n,m;
	scanf("%lld%lld",&n,&m);
	rep(i,0,n){
		int t;
		scanf("%d",&t);
		a[t]++;
	}
	rep(i,0,m){
		int t;
		scanf("%d",&t);
		b[t]++;
	}
	int cnt=0;
	rep(i,0,200005)if(b[i]){
		x[cnt].nxt=i;
		x[cnt].n=i;
		x[cnt].c=b[i];
		PQpush(h,cnt);
		cnt++;
	}
	
	ll ans=0,temp=0,pre=0;
	rep(i,0,200005)if(a[i]){
		temp+=(i-pre)*m;
		pre=i;
		while(x[h[1]].nxt<=i){
			int k=PQpop(h);
			ll nnxt=(i+x[k].n)/x[k].n*x[k].n;
			temp-=(nnxt-x[k].nxt)*x[k].c;
			x[k].nxt=nnxt;
			PQpush(h,k);
		}
		ans+=temp*a[i];
	}
	printf("%lld\n",ans);
}