Code:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define br putchar('\n')
#define _x fixed << setprecision
#define debug(x) cerr<< #x << '=' << x << '\n'
#define ok() cout << "Yes\n"
#define gg() cout << "No\n"
#define mem(a, b) memset(a, b, sizeof(a));
#define rep(i, a, b) for (int i = a;i <= b; ++i)
#define rrep(i, a, b) for(int i = a; i >= b; --i)
#define ALL(a) (a).begin(), (a).end()
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
using namespace std;
typedef pair<int, int> PII;
int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1}, dy[] = {0, 1, 0, -1, 1, 1, -1, -1};
const int N = 100010;
int n, m, a[N], pre[N], sum;
map<int, vector<PII> >mp;
map<int, int> mp_pre;
void solve_0()
{
for(int i = 1; i <= n; ++i)
if(!mp_pre[pre[i]]) mp_pre[pre[i]] = i;
while(m -- )
{
int x; cin >> x;
if(x == 0) cout << 0 << endl;
else cout << (mp_pre[x] == 0 ? -1 : mp_pre[x]) << endl;
}
}
void solve()
{
bool ok = false;
if(sum < 0) {
ok = true;
sum = -sum;
for(int i = 1; i <= n; ++i) pre[i] = -pre[i];
}
// 同余域,后面要找到该域里面前缀和最大的位置,所以存储相反数,升序排序,二分查找第一个大于等于的位置
for(int i = 1; i <= n; ++i)
{
int y = (pre[i] % sum + sum ) % sum;
mp[y].push_back({-pre[i], i});
}
for(auto &it : mp)
sort(ALL(it.second));
while( m -- )
{
int x; cin >> x;
x = ok ? -x : x;
if(x == 0) cout << 0 << endl;
else
{
int xx = (x % sum + sum ) % sum;
if(mp.find(xx) == mp.end()) cout << "-1\n";
else
{
PII pos = {-x, 0};
int id = lower_bound(ALL(mp[xx]), pos) - mp[xx].begin();
if (id == mp[xx].size()) cout << "-1\n";
else
{
int ans = mp[xx][id].second;
ans += (x + mp[xx][id].first) / sum * n;
cout << ans << endl;
}
}
}
}
}
signed main(){
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
IOS;
int tt; cin >> tt;
while( tt -- )
{
mp.clear(), mp_pre.clear();
cin >> n >> m;
sum = 0;
for(int i = 1; i <= n; ++i){
cin >> a[i];
pre[i] = a[i] + pre[i - 1], sum += a[i];
}
sum == 0 ? solve_0() : solve();
}
return 0;
}