#include #include #define ll long long int #define pb push_back #define st first #define nd second #define pii pair #define mp make_pair #define pll pair #define ld long double #define ull unsigned long long #define double float using namespace std; // taken from https://cp-algorithms.com/algebra/fft.html const int N = 805; const int mod = 167772161; using cd = complex; const double PI = acos(-1); void fft(vector & a, bool invert) { int n = a.size(); if (n == 1) return; vector a0(n / 2), a1(n / 2); for (int i = 0; 2 * i < n; i++) { a0[i] = a[2*i]; a1[i] = a[2*i+1]; } fft(a0, invert); fft(a1, invert); double ang = 2 * PI / n * (invert ? -1 : 1); cd w(1), wn(cos(ang), sin(ang)); for (int i = 0; 2 * i < n; i++) { a[i] = a0[i] + w * a1[i]; a[i + n/2] = a0[i] - w * a1[i]; if (invert) { a[i] /= 2; a[i + n/2] /= 2; } w *= wn; } } vector multiply(vector const& a, vector const& b) { vector fa(a.begin(), a.end()), fb(b.begin(), b.end()); int n = 1; while (n < a.size() + b.size()) n <<= 1; fa.resize(n); fb.resize(n); fft(fa, false); fft(fb, false); for (int i = 0; i < n; i++) fa[i] *= fb[i]; fft(fa, true); vector result(n); for (int i = 0; i < n; i++) result[i] = round(fa[i].real()); return result; } const int nax = 405; int wagi[nax]; int pref[nax][nax][nax]; int suf[nax][nax][nax]; int ans[nax][nax]; void solve(){ int n; cin >> n; int k; cin >> k; for(int i=1;i<=n;i++) cin >> wagi[i]; //int n = 400; // int k = 400; //for(int i=1;i<=n;i++) wagi[i] = i; pref[0][0][0] = 1; suf[n + 1][0][0] = 1; for(int i=1;i<=n;i++){ for(int j=0;j<=i;j++){ for(int c=0;c<=k;c++){ pref[i][j][c] = pref[i - 1][j][c]; if(j >= 1 && c >= wagi[i]){ pref[i][j][c] += pref[i - 1][j - 1][c - wagi[i]]; if(pref[i][j][c] >= mod) pref[i][j][c] -= mod; } } } } for(int i=n;i>=1;i--){ for(int j=0;j<=n-i+1;j++){ for(int c=0;c<=k;c++){ suf[i][j][c] = suf[i + 1][j][c]; if(j >= 1 && c >= wagi[i]){ suf[i][j][c] += suf[i + 1][j - 1][c - wagi[i]]; if(suf[i][j][c] >= mod) suf[i][j][c] -= mod; } } } } vector tmp; for(int s=1;s<=n;s++){ for(int WL=0;WL<=k;WL++){ vector one, two; for(int c=0;c= 0 && bylo < nax){ two[ile] -= suf[s + 1][ile][bylo]; if(two[ile] < 0) two[ile] += mod; } if(nowe >= 0 && nowe < nax){ two[ile] += suf[s + 1][ile][nowe]; if(two[ile] >= mod) two[ile] -= mod; } } } tmp = two; auto c = multiply(one, two); for(int j=0;j> tt; while(tt--) solve(); return 0; } //C:\Users\Przemek\Desktop\PROJEKCIK\ctu