Problem: 2050C - Uninteresting Number
Language: C++20 (GCC 13-64)

Previous submission (verdict: Time limit exceeded on test 2):
// ## Yuji snippet ##//



#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

#define ll long long

#define ff first

#define ss second

#define pb push_back

#define ppb pop_back

#define ld long double

#define ull unsigned long long

#define pii pair<int, int>

#define all(v) v.begin(), v.end()

#define rall(v) v.rbegin(), v.rend()

#define pll pair<ll, ll>

#define fr(a, b, i) for (ll i = a; i < b; i++)

#define fre(a, b, i) for (ll i = a; i <= b; i++)

#define srt(a) sort(a.begin(), a.end())

#define rsrt(a) sort(a.rbegin(), a.rend())

#define rv(a) reverse(a.begin(), a.end())

#define vi vector<int>

#define vvi vector<vector<int>>

#define vvll vector<vector<ll>>

#define vl vector<long>

#define vll vector<long long>

#define umi unordered_map<int, int>

#define mi map<int, int>

#define pq priority_queue<int>

#define mpq priority_queue<int, vi, greater<int>>

#define pqll priority_queue<ll>

#define mpqll priority_queue<ll, vll, greater<ll>>

#define vc vector<char>

#define mod 1000000007

#define INF 4e18

#define inf 1e9

#include <bitset>

using namespace std;

using namespace __gnu_pbds;

// typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

// find_by_order - give element at xth index

//  order_of_key - find no of elements smaller than x

ll dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

/*-------------------------factorial and modinv-------------------------*/

//(a/b)%mod = ((a%mod)*((b^(mod-2))%mod))%mod



ll fact[1000004];

ll modinv[1000004];



// finding power of something

ll power(ll a, ll b, ll m = mod)

{

    ll res = 1;

    while (b > 0)

    {

        if (b & 1)

            res = (res * a) % m;

        a = (a * a) % m;

        b = b >> 1;

    }

    return res;

    // log(x)

}



void precomp()

{

    modinv[0] = 1;

    fact[0] = 1;

    for (ll i = 1; i <= 1000000; i++)

    {

        fact[i] = (fact[i - 1] * i) % mod;

        modinv[i] = power(fact[i], mod - 2);

    }

}



// nCr calculation

ll ncr(ll n, ll r)

{

    if (n < 0 || r < 0 || r > n)

        return 0;



    return (((fact[n] * modinv[r]) % mod) * modinv[n - r]) % mod;

}



/*-------------------------SIEVE AND PRIME-------------------------*/



// check whether number is prime or not for first 1000004 whole numbers only

vll prime(1);

void sieve()

{

    prime.resize(1000004, 1);

    prime[0] = prime[1] = false;



    for (ll i = 2; i <= 1000004; i++)

    {

        for (ll j = i * i; j <= 1000004; j += i)

        {

            prime[j] = false;

        }

    }

}



// give first n prime numbers

vll primeGenerator(ll n)

{

    ll *arr = new ll[n + 1]();

    vector<ll> vect;

    for (ll i = 2; i <= n; i++)

        if (arr[i] == 0)

        {

            vect.pb(i);

            for (ll j = 2 * i; j <= n; j += i)

                arr[j] = 1;

        }

    return vect;

}



/*-------------------------LCM-------------------------*/



ll lcm(ll a, ll b)

{

    return a / (__gcd(a, b))*b;

}



// mod stuff starts here

ll invmod(ll a, ll m = mod) { return power(a, m - 2, m); } // For prime mod



ll MOD(ll x)

{

    return ((x % mod + mod) % mod);

}



ll mAdd(ll a, ll b, ll m = mod)

{

    a = a % m;

    b = b % m;

    return (((a + b) % m) + m) % m;

}

ll mSub(ll a, ll b, ll m = mod)

{

    a = a % m;

    b = b % m;

    return (((a - b) % m) + m) % m;

}

ll mMul(ll a, ll b, ll m = mod)

{

    a = a % m;

    b = b % m;

    return (((a * b) % m) + m) % m;

}

ll mDiv(ll a, ll b, ll m = mod)

{

    a = a % m;

    b = b % m;

    return mMul(a, invmod(b, m), m);

}



/*-------------------------DSU begin-------------------------*/



class DSU

{

private:

    vi parent, size;

    int components;



public:

    DSU(int n)

    {

        for (int i = 0; i <= n; i++)

        {

            parent.push_back(i);

            size.push_back(1);

        }

        components = n;

    }

    int getPar(int node)

    {

        if (parent[node] == node)

            return node;

        return parent[node] = getPar(parent[node]);

    }

    void unite(int u, int v)

    {

        int pu = getPar(u);

        int pv = getPar(v);

        if (pu == pv)

            return;

        if (size[pu] < size[pv])

        {

            parent[pu] = pv;

            size[pv] += size[pu];

        }

        else

        {

            parent[pv] = pu;

            size[pu] += size[pv];

        }

        components--;

    }

    int component_size(int n)

    {

        int p = getPar(n);

        return size[p];

    }



    int number_of_compoents()

    {

        return components - 1;

    }

};



/*-------------------------DSU ends-------------------------*/



/*-------------------------SOLUTION-------------------------*/



ll dp[100001][10];



ll f(ll i, ll sum, vll &a)

{

    if (sum == 9)

        return 1;

    if (i >= a.size())

        return 0;



    sum %= 9;

    if (dp[i][sum] != -1)

        return dp[i][sum];



    ll ntake = f(i + 1, sum, a);

    ll take = f(i + 1, sum + a[i], a);



    return dp[i][sum] = mAdd(take, ntake);

}



void solve()

{

    cout << fixed << setprecision(25);

    string s;

    cin >> s;

    int sum = 0;

    vll a;

    for (auto i : s)

    {

        sum += (i - '0');

        ll tmp = i - '0';

        if (tmp * tmp < 10)

        {

            a.pb(tmp * (tmp - 1));

        }

    }

    if (sum % 9 == 0)

    {

        cout << "YES\n";

        return;

    }

    sum = sum % 9;

    memset(dp, -1, sizeof(dp));

    ll ans = f(0, sum, a);

    if (ans > 0)

    {

        cout << "YES\n";

    }

    else

        cout << "NO\n";

}

int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    int t;

    cin >> t;

    // precomp();

    while (t--)

    {

        solve();

    }

    return 0;

}

Submission (verdict: Accepted):
// ## Yuji snippet ##//



#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

#define ll long long

#define ff first

#define ss second

#define pb push_back

#define ppb pop_back

#define ld long double

#define ull unsigned long long

#define pii pair<int, int>

#define all(v) v.begin(), v.end()

#define rall(v) v.rbegin(), v.rend()

#define pll pair<ll, ll>

#define fr(a, b, i) for (ll i = a; i < b; i++)

#define fre(a, b, i) for (ll i = a; i <= b; i++)

#define srt(a) sort(a.begin(), a.end())

#define rsrt(a) sort(a.rbegin(), a.rend())

#define rv(a) reverse(a.begin(), a.end())

#define vi vector<int>

#define vvi vector<vector<int>>

#define vvll vector<vector<ll>>

#define vl vector<long>

#define vll vector<long long>

#define umi unordered_map<int, int>

#define mi map<int, int>

#define pq priority_queue<int>

#define mpq priority_queue<int, vi, greater<int>>

#define pqll priority_queue<ll>

#define mpqll priority_queue<ll, vll, greater<ll>>

#define vc vector<char>

#define mod 1000000007

#define INF 4e18

#define inf 1e9

#include <bitset>

using namespace std;

using namespace __gnu_pbds;

// typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

// find_by_order - give element at xth index

//  order_of_key - find no of elements smaller than x

ll dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

/*-------------------------factorial and modinv-------------------------*/

//(a/b)%mod = ((a%mod)*((b^(mod-2))%mod))%mod



ll fact[1000004];

ll modinv[1000004];



// finding power of something

ll power(ll a, ll b, ll m = mod)

{

    ll res = 1;

    while (b > 0)

    {

        if (b & 1)

            res = (res * a) % m;

        a = (a * a) % m;

        b = b >> 1;

    }

    return res;

    // log(x)

}



void precomp()

{

    modinv[0] = 1;

    fact[0] = 1;

    for (ll i = 1; i <= 1000000; i++)

    {

        fact[i] = (fact[i - 1] * i) % mod;

        modinv[i] = power(fact[i], mod - 2);

    }

}



// nCr calculation

ll ncr(ll n, ll r)

{

    if (n < 0 || r < 0 || r > n)

        return 0;



    return (((fact[n] * modinv[r]) % mod) * modinv[n - r]) % mod;

}



/*-------------------------SIEVE AND PRIME-------------------------*/



// check whether number is prime or not for first 1000004 whole numbers only

vll prime(1);

void sieve()

{

    prime.resize(1000004, 1);

    prime[0] = prime[1] = false;



    for (ll i = 2; i <= 1000004; i++)

    {

        for (ll j = i * i; j <= 1000004; j += i)

        {

            prime[j] = false;

        }

    }

}



// give first n prime numbers

vll primeGenerator(ll n)

{

    ll *arr = new ll[n + 1]();

    vector<ll> vect;

    for (ll i = 2; i <= n; i++)

        if (arr[i] == 0)

        {

            vect.pb(i);

            for (ll j = 2 * i; j <= n; j += i)

                arr[j] = 1;

        }

    return vect;

}



/*-------------------------LCM-------------------------*/



ll lcm(ll a, ll b)

{

    return a / (__gcd(a, b))*b;

}



// mod stuff starts here

ll invmod(ll a, ll m = mod) { return power(a, m - 2, m); } // For prime mod



ll MOD(ll x)

{

    return ((x % mod + mod) % mod);

}



ll mAdd(ll a, ll b, ll m = mod)

{

    a = a % m;

    b = b % m;

    return (((a + b) % m) + m) % m;

}

ll mSub(ll a, ll b, ll m = mod)

{

    a = a % m;

    b = b % m;

    return (((a - b) % m) + m) % m;

}

ll mMul(ll a, ll b, ll m = mod)

{

    a = a % m;

    b = b % m;

    return (((a * b) % m) + m) % m;

}

ll mDiv(ll a, ll b, ll m = mod)

{

    a = a % m;

    b = b % m;

    return mMul(a, invmod(b, m), m);

}



/*-------------------------DSU begin-------------------------*/



class DSU

{

private:

    vi parent, size;

    int components;



public:

    DSU(int n)

    {

        for (int i = 0; i <= n; i++)

        {

            parent.push_back(i);

            size.push_back(1);

        }

        components = n;

    }

    int getPar(int node)

    {

        if (parent[node] == node)

            return node;

        return parent[node] = getPar(parent[node]);

    }

    void unite(int u, int v)

    {

        int pu = getPar(u);

        int pv = getPar(v);

        if (pu == pv)

            return;

        if (size[pu] < size[pv])

        {

            parent[pu] = pv;

            size[pv] += size[pu];

        }

        else

        {

            parent[pv] = pu;

            size[pu] += size[pv];

        }

        components--;

    }

    int component_size(int n)

    {

        int p = getPar(n);

        return size[p];

    }



    int number_of_compoents()

    {

        return components - 1;

    }

};



/*-------------------------DSU ends-------------------------*/



/*-------------------------SOLUTION-------------------------*/



int dp[100001][10];



int f(int i, int sum, vi &a)

{

    if (sum % 9 == 0)

        return 1;

    if (i >= a.size())

        return 0;



    sum %= 9;

    if (dp[i][sum] != -1)

        return dp[i][sum];



    int ntake = f(i + 1, sum, a);

    int take = f(i + 1, sum + a[i], a);



    return dp[i][sum] = mAdd(take, ntake);

}



void solve()

{

    cout << fixed << setprecision(25);

    string s;

    cin >> s;

    int sum = 0;

    vi a;

    for (auto i : s)

    {

        sum += (i - '0');

        int tmp = i - '0';

        if (tmp * tmp < 10)

        {

            a.pb(tmp * (tmp - 1));

        }

    }

    if (sum % 9 == 0)

    {

        cout << "YES\n";

        return;

    }

    sum = sum % 9;

    memset(dp, -1, sizeof(dp));

    int ans = f(0, sum, a);

    if (ans > 0)

    {

        cout << "YES\n";

    }

    else

        cout << "NO\n";

}

int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(NULL);

    int t;

    cin >> t;

    // precomp();

    while (t--)

    {

        solve();

    }

    return 0;

}