Problem:
Sum of Sequences

Problem

n個の要素を持つ数列A、m個の要素を持つ数列B、
それぞれが整数cからなるq個のクエリが与えられる。

各クエリについて、

数列Aの[la,ra]を全て足した数と数列Bの[lb,rb]を全て足した数の差の絶対値がcになるla,ra,lb,rb (0 ≤ la ≤ ra ≤ n−1, 0 ≤ lb ≤ rb ≤ m−1, 配列の番号は0番から始まる) の組み合わせの数を求めよ。

Input

n m q
a0 a1 ... an−1
b0 b1 ... bm−1
c0
c1
...
cq−1

入力は全て整数で与えられる。

1行目に数列の要素数nとm、クエリ数qが与えられる。

2行目に数列Aの要素、3行目に数列Bの要素が空白区切りで与えられる。

4行目からq行に各クエリの値ciが与えられる。

Constraints

1 ≤ n, m ≤ 4×104

1 ≤ q ≤ 105

1 ≤ ai, bi ≤ 5

0 ≤ ci ≤ 2×105

Output

出力はq行からなる。各クエリの組み合わせの数を順番に一行に出力せよ。

Sample Input 1

3 3 1
1 2 3
3 1 2
3

Sample Output 1

6

Sample Input 2

5 4 2
1 2 3 4 5
2 2 2 2
11
12

Sample Output 2

3
4

Solution in C++11 (judge verdict: Time Limit Exceeded)

#include <bits/stdc++.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using namespace std;
using ll=long long;

const ll mod=1000000007LL;
const int dx[8]={1,0,-1,0,1,-1,-1,1};
const int dy[8]={0,1,0,-1,1,1,-1,-1};

using R=long double;
const R eps=1e-11; // [-1000:1000]->EPS=1e-8 [-10000:10000]->EPS=1e-7
const R pi=acos(-1);
const R inf=1e40;
inline int sgn(const R& r){ return (r > eps) - (r < -eps);}
inline int sgn(const R& a, const R &b){ return sgn(a-b); }
inline R sq(R x){return sqrt(max<R>(x,0.0));}

using C=complex<R>;

void fft(vector<C> &a,bool inv){
	const int n=a.size();
 	const R sign=(inv?-1.0:1.0);
	
	int rj=0;
	rep(j,1,n-1){
		for(int k=n>>1;k>(rj^=k);k>>=1);
		if(j<rj) swap(a[j],a[rj]);
 	}

 	for(int m=1;m<n;m<<=1){
 		C wn=exp(C(0.0,sign*pi/m)),w=1.0;
		rep(p,m){
			for(int s=p;s<n;s+=2*m){
				C u=a[s],v=a[s+m]*w;
				a[s]=u+v,a[s+m]=u-v;				
			}
			w*=wn;
		}
	}
	if(inv) rep(i,n) a[i]/=n;
}

vector<C> convolution(vector<C> a,vector<C> b){
	int fft_size=1;
	while (fft_size < a.size()+b.size()) fft_size <<= 1;
	
	a.resize(fft_size),fft(a,0);
	b.resize(fft_size),fft(b,0);
	
	vector<C> c(fft_size,0.0);
	rep(i,fft_size) c[i]=a[i]*b[i];

	fft(c,1);
	return c;
}

int a[40010],b[40010];
const int limit=400001;
const int offset=200000;


int main(void){
	int n,m,q;
	cin >> n >> m >> q;
	rep(i,n) cin >> a[i];
	rep(i,m) cin >> b[i];

	vector<C> ares,bres,ans;
	
	{
		vector<C> plus(limit,0.0),minus(limit,0.0);
		int sum=0; plus[sum+offset]+=1.0,minus[-sum+offset]+=1.0;
		rep(i,n) sum+=a[i],plus[sum+offset]+=1.0,minus[-sum+offset]+=1.0;
		ares=convolution(plus,minus);
	}

	{
		vector<C> plus(limit,0.0),minus(limit,0.0);
		int sum=0; plus[sum+offset]+=1.0,minus[-sum+offset]+=1.0;
		rep(i,m) sum+=b[i],plus[sum+offset]+=1.0,minus[-sum+offset]+=1.0;
		bres=convolution(plus,minus);
	}


	rep(i,2*limit){
		if(i<=2*offset)
			ares[i]=0.0,bres[i]=0.0;
		else{
			ares[i]=int(real(ares[i])+0.5);
			bres[i]=int(real(bres[i])+0.5);
		}
	}

	{
		vector<C> plus(limit,0.0),minus(limit,0.0);
		rep(i,2*limit){
			if(i<=2*offset) continue; 
			int num=i-2*offset;
			plus[num+offset]=ares[i];
			minus[-num+offset]=bres[i];
		}
		ans=convolution(plus,minus);
	}

	rep(loop,q){
		int c;
		cin >> c;
		if(c==0)
			cout << int(real(ans[2*offset])+0.5) << endl;
		else
			cout << int(real(ans[c+2*offset])+0.5)+int(real(ans[-c+2*offset])+0.5) << endl;
	}
	return 0;
}