1+ // #pragma GCC optimize("Ofast")
2+ // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma")
3+ // #pragma GCC optimize("unroll-loops")
4+ #include < bits/stdc++.h>
5+ using namespace std ;
6+
7+ typedef long long ll;
8+ typedef vector<int > vi;
9+ #define fast_cin () ios_base::sync_with_stdio(false ); cin.tie(NULL ); cout.tie(NULL );
10+
11+
12+ int n, m;
13+ vector<int > a, b;
14+ vector<vector<ll>> memo;
15+ int main (){
16+ int tc;
17+ cin >> tc;
18+ while (tc--){
19+ cin >> n >> m;
20+ a.assign (n, 0 );
21+ b.assign (m, 0 );
22+ for (int i = 0 ; i < n; i++){
23+ cin >> a[i];
24+ }
25+ for (int i = 0 ; i < m; i++){
26+ cin >> b[i];
27+ }
28+
29+ ll inf = 1e18 ;
30+ memo.assign (m+1 , vector<ll>(n+1 , inf));
31+
32+ // dp(_, n) = 0
33+ for (int k = 0 ; k <= m; k++){
34+ memo[k][n] = 0 ;
35+ }
36+
37+ for (int k=m; k >= 1 ; k--){
38+ priority_queue<pair<ll, int >, vector<pair<ll, int >>, greater<pair<ll, int >>> pq; // contains {dp(k,j)} for relevant j > i, lazy deletion
39+ pq.emplace (memo[k][n], n);
40+ int curSum = 0 ; // sum of a(i+1)..a(curBack)
41+ int curBack = n-1 ; // we are considering dp(k, i+1)..dp(k, curBack)
42+
43+ for (int i=n-1 ; i >= 0 ; i--){
44+ if (k < m) memo[k][i] = memo[k+1 ][i]; // we can try incrementing k
45+ curSum += a[i];
46+ while (curBack >= i && curSum > b[k-1 ]){
47+ curSum -= a[curBack];
48+ curBack--;
49+ }
50+
51+ // curSum = a(i)..a(curBack) <= b[k-1]
52+ if (curBack < i){ // not possible to grab anything
53+ pq.emplace (memo[k][i], i);
54+ continue ;
55+ }
56+
57+ while (!pq.empty () && pq.top ().second > curBack + 1 ){
58+ pq.pop ();
59+ }
60+ if (!pq.empty ()){
61+ ll val = pq.top ().first ;
62+ memo[k][i] = min (memo[k][i], val + (m-k));
63+ }
64+
65+ pq.emplace (memo[k][i], i);
66+ // cout << "k: " << k << " i: " << i << " memo: " << memo[k][i] << endl;
67+ }
68+ }
69+
70+ vector<vector<ll>> numOps (m+1 , vector<ll>(n+1 , 0 ));
71+ const ll MOD = 1e9 + 7 ;
72+ for (int k = 0 ; k <= m; k++){
73+ numOps[k][n] = 1 ;
74+ }
75+
76+ for (int k=m; k >= 1 ; k--){
77+
78+ unordered_map<ll, ll> cellswithValue;
79+ cellswithValue[memo[k][n]] = numOps[k][n];
80+ int curSum = 0 ; // sum of a(i+1)..a(curBack)
81+ int curBack = n-1 ; // we are considering dp(k, i+1)..dp(k, curBack)
82+
83+ for (int i=n-1 ; i >= 0 ; i--){
84+ if (k < m){
85+ if (memo[k][i] == memo[k+1 ][i]){
86+ numOps[k][i] = numOps[k+1 ][i];
87+ }
88+ }
89+
90+ curSum += a[i];
91+ while (curBack >= i && curSum > b[k-1 ]){
92+ curSum -= a[curBack];
93+ cellswithValue[memo[k][curBack+1 ]] -= numOps[k][curBack+1 ];
94+ cellswithValue[memo[k][curBack+1 ]] %= MOD;
95+ curBack--;
96+ }
97+
98+ // curSum = a(i)..a(curBack) <= b[k-1]
99+ if (curBack < i){ // not possible to grab anything
100+ cellswithValue[memo[k][i]] += numOps[k][i];
101+ cellswithValue[memo[k][i]] %= MOD;
102+ continue ;
103+ }
104+
105+
106+ numOps[k][i] += cellswithValue[memo[k][i] - (m-k)];
107+ numOps[k][i] %= MOD;
108+
109+ cellswithValue[memo[k][i]] += numOps[k][i];
110+ cellswithValue[memo[k][i]] %= MOD;
111+ }
112+ }
113+
114+ if (memo[1 ][0 ] >= inf){
115+ cout << -1 << endl;
116+ } else {
117+ cout << memo[1 ][0 ] << " " << (numOps[1 ][0 ]+MOD)%MOD << endl;
118+ }
119+
120+
121+
122+
123+ }
124+
125+ return 0 ;
126+ }
0 commit comments