Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

Rich Substrings CodeChef Solution

Problem -Rich Substrings CodeChef Solution

This website is dedicated for CodeChef solution where we will publish right solution of all your favourite CodeChef problems along with detailed explanatory of different competitive programming concepts and languages.

Rich Substrings CodeChef Solution in C++17

#include<bits/stdc++.h>
using namespace std;

using ll = long long;
using vi = vector<int>;
#define pb push_back
#define pi pair<int,int>
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()

void setIO() {
	ios_base::sync_with_stdio(0);cin.tie(0);
	#ifndef ONLINE_JUDGE
		freopen("input.txt","r",stdin);
		freopen("output.txt","w",stdout);
	#endif
}

set<int> F;

int main()
{
	setIO();

	int t;
	cin>>t;
	while(t--){
		int n,q;
		cin>>n>>q;
		string s;
		cin>>s;
		set<int>F;
		for(int i=0;i+2<s.size();++i){
			if(s[i+1]==s[i]||s[i+2]==s[i]||s[i+1]==s[i+2]){
				F.insert(i+1);
			}
		}
		while(q--){
			int l,r;
			cin>>l>>r;
			int x=*F.lower_bound(l);
			if(x>=l&&x<=r-2){
				cout<<"YES\n";
			}
			else{
				cout<<"NO\n";
			}
		}
	}
	return 0;
}

Rich Substrings CodeChef Solution in C++14

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip> 
#include <math.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <complex>

using namespace std;

typedef long long LL;
typedef pair<LL, LL> PL;
typedef vector<LL> VL;
typedef vector<PL> VPL;
typedef vector<VL> VVL;

typedef pair<int, int> PI;
typedef vector<int> VI;
typedef vector<PI> VPI;
typedef vector<vector<int>> VVI;
typedef vector<vector<PI>> VVPI;

typedef long double LD;
typedef pair<LD, LD> PLDLD;

typedef complex<double> CD;
typedef vector<CD> VCD;

typedef vector<string> VS;

#define MP make_pair
#define PB push_back
#define F first
#define S second
#define LB lower_bound
#define UB upper_bound

#define SZ(x) ((int)x.size())
#define LEN(x) ((int)x.length())
#define ALL(x) begin(x), end(x)
#define RSZ resize
#define ASS assign
#define REV(x) reverse(x.begin(), x.end());



#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)


const LL INF = 1E18;
const int MAXX = 300005;
const LD PAI = 4 * atan((LD)1);

template <typename T>
class fenwick_tree {
public:
    vector<T> fenw;
    int n;

    fenwick_tree(int _n) : n(_n) {
        fenw.resize(n);
    }

    void update(int x, T v) {
        while (x < n) {
            fenw[x] += v;
            x |= (x + 1);
            //x += (x & (-x));
        }
    }

    T query(int x) {
        T v{};
        while (x >= 0) {
            v += fenw[x];
            x = (x & (x + 1)) - 1;
        }
        return v;
    }

    T query_full(int a, int b) {		// range query
        return query(b) - ((a <= 1) ? 0 : query(a - 1));
    }
};

template <typename T>
vector<T> serialize(vector<T> a, int startvalue = 0) {
    int n = a.size(), i, j, k, ct;
    vector<T> ans(n);
    map<T, T> id;
    for (auto p : a) id[p] = 0;
    ct = startvalue;
    for (auto p : id) id[p.first] = ct++;
    for (i = 0; i < n; i++) ans[i] = id[a[i]];
    return ans;
}

template <typename T>
class segment_tree {
    vector<T> t;
    T VERYBIG;
    bool ISMAXRANGE;
    int size;
public:
    segment_tree(int n, bool range_max = true) {
        if (is_same<T, int>::value) VERYBIG = (1 << 30);
        else if (is_same<T, LL>::value) VERYBIG = (1LL << 60);
        //else if (is_same<T, PII>::value) VERYBIG = PII({ 1E9, 1E9 });
        //else if (is_same<T, PLL>::value) VERYBIG = { 1LL << 60, 1LL << 60 };

        ISMAXRANGE = range_max;

        if (ISMAXRANGE) t.assign(4 * n + 1, 0);
        else t.assign(4 * n + 1, VERYBIG);
        size = n;
    }

    void initialize_array(vector<T>& v) {
        initialize_with_array(1, 0, size - 1, v);
    }

    void initialize_with_array(int startpos, int l, int r, vector<T>& v) {
        if (l == r) {
            t[startpos] = v[l];
        }
        else {
            int m = (l + r) / 2;
            initialize_with_array(2 * startpos, l, m, v);
            initialize_with_array(2 * startpos + 1, m + 1, r, v);

            if (ISMAXRANGE == 1) t[startpos] = max(t[startpos * 2], t[startpos * 2 + 1]);
            else  t[startpos] = min(t[startpos * 2], t[startpos * 2 + 1]);
        }
    }

    void update(int index, T val) { // insert val into location index
        update_full(1, 0, size - 1, index, val);
    }

    void update_full(int startpos, int l, int r, int index, T val) {
        if (l == r) {
            t[startpos] = val;
        }
        else {
            int m = (l + r) / 2;
            if (index <= m) update_full(2 * startpos, l, m, index, val);
            else update_full(2 * startpos + 1, m + 1, r, index, val);

            if (ISMAXRANGE) t[startpos] = max(t[startpos * 2], t[startpos * 2 + 1]);
            else t[startpos] = min(t[startpos * 2], t[startpos * 2 + 1]);
        }
    }

    T query(int l, int r) {  // get range min/max between l and r
        if (l > r) {
            if (ISMAXRANGE) return 0;
            else return VERYBIG;
        }
        return query_full(1, 0, size - 1, l, r);
    }

    T query_full(int startpos, int left, int right, int l, int r) {	 // left/right = current range, l/r = intended query range
        if ((left >= l) && (right <= r)) return t[startpos];
        int m = (left + right) / 2;
        T ans;
        if (ISMAXRANGE) ans = -VERYBIG;
        else ans = VERYBIG;
        if (m >= l) {
            if (ISMAXRANGE) ans = max(ans, query_full(startpos * 2, left, m, l, r));
            else ans = min(ans, query_full(startpos * 2, left, m, l, r));
        }
        if (m + 1 <= r) {
            if (ISMAXRANGE) ans = max(ans, query_full(startpos * 2 + 1, m + 1, right, l, r));
            else ans = min(ans, query_full(startpos * 2 + 1, m + 1, right, l, r));
        }
        return ans;
    }
};

//#define MOD 1000000007
int MOD = 1, root = 2; // 998244353

template<class T> T invGeneral(T a, T b) {
    a %= b; if (a == 0) return b == 1 ? 0 : -1;
    T x = invGeneral(b, a);
    return x == -1 ? -1 : ((1 - (LL)b * x) / a + b) % b;
}

template<class T> struct modular {
    T val;
    explicit operator T() const { return val; }
    modular() { val = 0; }
    modular(const LL& v) {
        val = (-MOD <= v && v <= MOD) ? v : v % MOD;
        if (val < 0) val += MOD;
    }

    friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
    friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
    friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }
    friend bool operator<(const modular& a, const modular& b) { return a.val < b.val; }

    modular operator-() const { return modular(-val); }
    modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
    modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
    modular& operator*=(const modular& m) { val = (LL)val * m.val % MOD; return *this; }
    friend modular pow(modular a, LL p) {
        modular ans = 1; for (; p; p /= 2, a *= a) if (p & 1) ans *= a;
        return ans;
    }
    friend modular inv(const modular& a) {
        auto i = invGeneral(a.val, MOD); assert(i != -1);
        return i;
    } // equivalent to return exp(b,MOD-2) if MOD is prime
    modular& operator/=(const modular& m) { return (*this) *= inv(m); }

    friend modular operator+(modular a, const modular& b) { return a += b; }
    friend modular operator-(modular a, const modular& b) { return a -= b; }
    friend modular operator*(modular a, const modular& b) { return a *= b; }

    friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi, mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

namespace vecOp {
    template<class T> vector<T> rev(vector<T> v) { reverse(ALL(v)); return v; }
    template<class T> vector<T> shift(vector<T> v, int x) { v.insert(v.begin(), x, 0); return v; }

    template<class T> vector<T>& operator+=(vector<T>& l, const vector<T>& r) {
        l.rSZ(max(SZ(l), SZ(r))); F0R(i, SZ(r)) l[i] += r[i]; return l;
    }
    template<class T> vector<T>& operator-=(vector<T>& l, const vector<T>& r) {
        l.rSZ(max(SZ(l), SZ(r))); F0R(i, SZ(r)) l[i] -= r[i]; return l;
    }
    template<class T> vector<T>& operator*=(vector<T>& l, const T& r) { trav(t, l) t *= r; return l; }
    template<class T> vector<T>& operator/=(vector<T>& l, const T& r) { trav(t, l) t /= r; return l; }

    template<class T> vector<T> operator+(vector<T> l, const vector<T>& r) { return l += r; }
    template<class T> vector<T> operator-(vector<T> l, const vector<T>& r) { return l -= r; }
    template<class T> vector<T> operator*(vector<T> l, const T& r) { return l *= r; }
    template<class T> vector<T> operator*(const T& r, const vector<T>& l) { return l * r; }
    template<class T> vector<T> operator/(vector<T> l, const T& r) { return l /= r; }

    template<class T> vector<T> operator*(const vector<T>& l, const vector<T>& r) {
        if (min(SZ(l), SZ(r)) == 0) return {};
        vector<T> x(SZ(l) + SZ(r) - 1); F0R(i, SZ(l)) F0R(j, SZ(r)) x[i + j] += l[i] * r[j];
        return x;
    }
    template<class T> vector<T>& operator*=(vector<T>& l, const vector<T>& r) { return l = l * r; }

    template<class T> vector<T> rem(vector<T> a, vector<T> b) {
        while (SZ(b) && b.back() == 0) b.pop_back();
        assert(SZ(b)); b /= b.back();
        while (SZ(a) >= SZ(b)) {
            a -= a.back() * shift(b, SZ(a) - SZ(b));
            while (SZ(a) && a.back() == 0) a.pop_back();
        }
        return a;
    }
    template<class T> vector<T> interpolate(vector<pair<T, T>> v) {
        vector<T> ret;
        F0R(i, SZ(v)) {
            vector<T> prod = { 1 };
            T todiv = 1;
            F0R(j, SZ(v)) if (i != j) {
                todiv *= v[i].f - v[j].f;
                vector<T> tmp = { -v[j].f,1 }; prod *= tmp;
            }
            ret += prod * (v[i].s / todiv);
        }
        return ret;
    }
}

using namespace vecOp;

class factorial {
public:
    LL MAXX, MOD;
    VL f, ff;

    factorial(LL maxx = 200010, LL mod = 998244353) {
        MAXX = maxx;
        MOD = mod;

        f.RSZ(MAXX);
        ff.RSZ(MAXX);

        f[0] = 1;
        for (int i = 1; i < MAXX; i++) f[i] = (f[i - 1] * i) % MOD;
        for (int i = 0; i < MAXX; i++) ff[i] = mul_inv(f[i], MOD);
    }

    long long mul_inv(long long a, long long b)
    {
        long long b0 = b, t, q;
        long long x0 = 0, x1 = 1;
        if (b == 1) return 1;
        while (a > 1) {
            q = a / b;
            t = b, b = a % b, a = t;
            t = x0, x0 = x1 - q * x0, x1 = t;
        }
        if (x1 < 0) x1 += b0;
        return x1;
    }

    long long division(long long a, long long b) {		// (a / b) mod p = ((a mod p) * (b^(-1) mod p)) mod p
        long long ans, inv;
        inv = mul_inv(b, MOD);
        ans = ((a % MOD) * inv) % MOD;
        return ans;
    }

    LL calcc(LL n, LL a) {
        if (n == a) return 1;
        if (n == 0) return 0;
        if (n < a) return 0;
        LL ans = (f[n] * ff[a]) % MOD;
        ans = (ans * ff[n - a]) % MOD;
        return ans;
    }

    LL calcp(LL n, LL a) {
        LL ans = (f[n] * ff[n - a]) % MOD;
        return ans;
    }

    LL exp(LL base, LL n) {
        base %= MOD;
        LL ans = 1, x = base, MAXLEVEL = 60, i;

        for (i = 0; i < MAXLEVEL; i++) {
            if ((1LL << i) > n) break;
            if ((1LL << i) & n) ans = (ans * x) % MOD;
            x = (x * x) % MOD;
        }
        return ans;
    }
};

#ifdef _MSC_VER 
//#include <intrin.h>
#endif

namespace FFT {
#ifdef _MSC_VER 
    int size(int s) {
        if (s == 0) return 0;
        unsigned long index;
        _BitScanReverse(&index, s);
        return index + 1;
    }
#else
    constexpr int size(int s) { return s > 1 ? 32 - __builtin_clz(s - 1) : 0; }
#endif

    template<class T> bool small(const vector<T>& a, const vector<T>& b) {
        return (LL)SZ(a) * SZ(b) <= 500000;
    }

    void genRoots(vmi& roots) { // primitive n-th roots of unity
        int n = SZ(roots); mi r = pow(mi(root), (MOD - 1) / n);
        roots[0] = 1; FOR(i, 1, n) roots[i] = roots[i - 1] * r;
    }
    void genRoots(VCD& roots) { // change cd to complex<double> instead?
        int n = SZ(roots); LD ang = 2 * PAI / n;
        F0R(i, n) roots[i] = CD(cos(ang * i), sin(ang * i)); // is there a way to do this more quickly?
    }

    template<class T> void fft(vector<T>& a, vector<T>& roots) {
        int n = SZ(a);
        for (int i = 1, j = 0; i < n; i++) { // sort by reverse bit representation
            int bit = n >> 1;
            for (; j & bit; bit >>= 1) j ^= bit;
            j ^= bit; if (i < j) swap(a[i], a[j]);
        }
        for (int len = 2; len <= n; len <<= 1)
            for (int i = 0; i < n; i += len)
                F0R(j, len / 2) {
                auto u = a[i + j], v = a[i + j + len / 2] * roots[n / len * j];
                a[i + j] = u + v, a[i + j + len / 2] = u - v;
            }
    }

    template<class T> vector<T> conv(vector<T> a, vector<T> b) {
        //if (small(a, b)) return a * b;
        int s = SZ(a) + SZ(b) - 1, n = 1 << size(s);
        vector<T> roots(n); genRoots(roots);

        a.RSZ(n), fft(a, roots); b.RSZ(n), fft(b, roots);
        F0R(i, n) a[i] *= b[i];
        reverse(begin(roots) + 1, end(roots)); fft(a, roots); // inverse FFT

        T in = T(1) / T(n); trav(x, a) x *= in;
        a.RSZ(s); return a;
    }

    VL conv(const VL& a, const VL& b) {
        //if (small(a, b)) return a * b;
        VCD X = conv(VCD(ALL(a)), VCD(ALL(b)));
        VL x(SZ(X)); F0R(i, SZ(X)) x[i] = round(X[i].real());
        return x;
    } // ~0.55s when SZ(a)=SZ(b)=1<<19

    VL conv(const VL& a, const VL& b, LL mod) { // http://codeforces.com/contest/960/submission/37085144
        //if (small(a, b)) return a * b;
        int s = SZ(a) + SZ(b) - 1, n = 1 << size(s);

        VCD v1(n), v2(n), r1(n), r2(n);
        F0R(i, SZ(a)) v1[i] = CD(a[i] >> 15, a[i] & 32767); // v1(x)=a0(x)+i*a1(x)
        F0R(i, SZ(b)) v2[i] = CD(b[i] >> 15, b[i] & 32767); // v2(x)=b0(x)+i*b1(x)

        VCD roots(n); genRoots(roots);
        fft(v1, roots), fft(v2, roots);
        F0R(i, n) {
            int j = (i ? (n - i) : i);
            CD ans1 = (v1[i] + conj(v1[j])) * CD(0.5, 0); // a0(x)
            CD ans2 = (v1[i] - conj(v1[j])) * CD(0, -0.5); // a1(x)
            CD ans3 = (v2[i] + conj(v2[j])) * CD(0.5, 0); // b0(x)
            CD ans4 = (v2[i] - conj(v2[j])) * CD(0, -0.5); // b1(x)
            r1[i] = (ans1 * ans3) + (ans1 * ans4) * CD(0, 1); // a0(x)*v2(x)
            r2[i] = (ans2 * ans3) + (ans2 * ans4) * CD(0, 1); // a1(x)*v2(x)
        }
        reverse(begin(roots) + 1, end(roots));
        fft(r1, roots), fft(r2, roots); F0R(i, n) r1[i] /= n, r2[i] /= n;

        VL ret(n);
        F0R(i, n) {
            LL av = (LL)round(r1[i].real()); // a0*b0
            LL bv = (LL)round(r1[i].imag()) + (LL)round(r2[i].real()); // a0*b1+a1*b0
            LL cv = (LL)round(r2[i].imag()); // a1*b1
            av %= mod, bv %= mod, cv %= mod;
            ret[i] = (av << 30) + (bv << 15) + cv;
            ret[i] = (ret[i] % mod + mod) % mod;
        }
        ret.resize(s);
        return ret;
    } // ~0.8s when SZ(a)=SZ(b)=1<<19
}
using namespace FFT;

long long gcd(long long a, long long b)
{
    while (b != 0) {
        long long t = b;
        b = a % b;
        a = t;
    }
    return a;
}



class tree {		// implementation of recurvie programming
    int ct;
public:
    int nn, root;				// # of nodes, id of root
    vector<int> parent;			// parent of each node; -1 if unassigned
    vector<int> depth;			// depth of each node
    vector<int> sz;				// subtree size of each node 
    vector<vector<int>> adj;	// adjacency list from each node
    vector<vector<int>> sons;	// sons list from each node

    // for cartesian_decomposition
    vector<int> in, out;		// starting and ending position of a subtree
    vector<int> pos;			// inorder of DFS

    // for LCA sparse table
    vector<vector<int>> pred;
    int MAXLEVEL;

    tree(int n) {
        nn = n;
        adj.clear();
        adj.resize(n);
    }

    void add_path(int a, int b) {
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    void add_directed_path(int a, int b) {
        adj[a].push_back(b);
    }

    void dfs_set_root(int id, bool cartesian_decomposition = false) {	// internal
        if (cartesian_decomposition) {
            in[id] = ct;
            pos[ct] = id;
            ct++;
        }

        sz[id]++;

        for (auto p : adj[id]) {
            if (parent[p] == -1) {
                parent[p] = id;
                depth[p] = depth[id] + 1;
                dfs_set_root(p, cartesian_decomposition);
                sz[id] += sz[p];

                sons[id].push_back(p);
            }
        }

        if (cartesian_decomposition) out[id] = ct - 1;
    }

    void set_root(int id, bool cartesian_decomposition = true) {		// set root of the tree and calculate necessary info
        if (cartesian_decomposition) {
            in.resize(nn);
            out.resize(nn);
            pos.resize(nn);
            ct = 0;
        }

        parent.assign(nn, -1);
        depth.assign(nn, -1);
        sz.assign(nn, 0);
        sons.clear();
        sons.resize(nn);

        // dfs_set_root(id, cartesian_decomposition);


        // set root using stack
        stack<pair<int, int>> st;		// id, # of sons processes
        st.push({ id, 0 });
        parent[id] = 0;
        depth[id] = 0;

        int ct = 0;

        while (!st.empty()) {
            int id = st.top().first, x = st.top().second;

            if (x == 0) {
                in[id] = ct;
                pos[ct] = id;
                sz[id] = 1;
                ct++;
            }

            if (x >= adj[id].size()) {
                out[id] = ct - 1;
                if (parent[id] != -1) {
                    sz[parent[id]] += sz[id];
                }
                st.pop();
            }
            else {

                st.top().second++;

                int p = adj[id][x];
                if (parent[p] == -1) {
                    parent[p] = id;
                    depth[p] = depth[id] + 1;
                    sons[id].push_back(p);
                    st.push({ p, 0 });
                }
            }
        }

        int i = 0;
    }

    void eulerian_tour_dfs(int root, vector<int>& ans) {
        ans.push_back(root);
        for (auto p : sons[root]) {
            eulerian_tour_dfs(p, ans);
            ans.push_back(root);
        }
    }

    vector<int> eulerian_tour(int root) {
        vector<int> ans;

        eulerian_tour_dfs(root, ans);

        return ans;
    }


    void prep_LCA() {		// prepare the sparse table for LCA calculation
        MAXLEVEL = 1;
        while ((1 << MAXLEVEL) < nn) MAXLEVEL++;
        MAXLEVEL++;

        pred.assign(MAXLEVEL, vector<int>(nn, 0));
        pred[0] = parent;

        int i, j, k;
        for (i = 1; i < MAXLEVEL; i++) {
            for (j = 0; j < nn; j++) {
                if (pred[i - 1][j] != -1) pred[i][j] = pred[i - 1][pred[i - 1][j]];
            }
        }
    }

    int get_p_ancestor(int a, int p) {		// get p-ancestor of node a;  need to call set_root() and prep_LCA() first
        int i;
        for (i = MAXLEVEL - 1; (i >= 0) && (p > 0) && (a != -1); i--) {
            if ((1 << i) & p) {
                p -= (1 << i);
                a = pred[i][a];
            }
        }
        return a;
    }

    int LCA(int a, int b) {		// get the LCA of a and b, need to call set_root() and prep_LCA() first
        int da = depth[a], db = depth[b];

        if (da > db) {
            swap(da, db);
            swap(a, b);
        }

        int i, j, k;
        for (i = MAXLEVEL - 1; i >= 0; i--) {
            if (db - (1 << i) >= da) {
                db -= (1 << i);
                b = pred[i][b];
            }
        }

        if (a == b) return a;

        for (i = MAXLEVEL - 1; i >= 0; i--) {
            if (pred[i][a] != pred[i][b]) {
                a = pred[i][a];
                b = pred[i][b];
            }
        }

        return parent[a];
    }

    int get_distance(int a, int b) {	// get distance between a and b, need to call set_root() and prep_LCA() first
        int c = LCA(a, b);
        int ans = depth[a] + depth[b] - 2 * depth[c];
        return ans;
    }

    int get_diameter() {
        int a, b, c, i, j, k, id, INF = nn + 100, ans;
        vector<int> dist(nn), last(nn);
        queue<int> q;

        if (nn == 1) return 0;

        // first pass, start with 1 -- any node
        a = 1;
        dist.assign(nn, INF);
        dist[a] = 0;
        q.push(a);

        while (!q.empty()) {
            id = q.front();
            q.pop();

            for (auto p : adj[id]) {
                if (dist[p] == INF) {
                    dist[p] = dist[id] + 1;
                    q.push(p);
                }
            }
        }

        // second pass, start from the most remote node id, collect last to get ID
        a = id;
        dist.assign(nn, INF);
        last.assign(nn, -1);
        dist[a] = 0;
        q.push(a);

        while (!q.empty()) {
            id = q.front();
            q.pop();

            for (auto p : adj[id]) {
                if (dist[p] == INF) {
                    dist[p] = dist[id] + 1;
                    last[p] = id;
                    q.push(p);
                }
            }
        }

        // a and id forms the diameter
        ans = dist[id];

        return ans;

        // construct the path of diamter in path
        vector<int> path;
        b = id;
        c = id;
        do {
            path.push_back(b);
            b = last[b];
        } while (b != -1);

        return ans;
    }
};


// Union-Find Disjoint Sets Library written in OOP manner, using both path compression and union by rank heuristics
// initialize: UnionFind UF(N)

class UnionFind {                                              // OOP style
private:
    vector<int> p, rank, setSize;
    // p = path toward the root of disjoint set; p[i] = i means it is root
    // rank = upper bound of the actual height of the tree; not reliable as accurate measure
    // setSize = size of each disjoint set

    int numSets;
public:
    UnionFind(int N) {
        setSize.assign(N, 1);
        numSets = N;
        rank.assign(N, 0);
        p.assign(N, 0);
        for (int i = 0; i < N; i++) p[i] = i;	// each belongs to its own set
    }

    int findSet(int i) {
        return (p[i] == i) ? i : (p[i] = findSet(p[i]));		// path compression: cut short of the path if possible
    }

    bool isSameSet(int i, int j) {
        return findSet(i) == findSet(j);
    }

    void unionSet(int i, int j) {
        if (!isSameSet(i, j)) {
            numSets--;
            int x = findSet(i), y = findSet(j);
            // rank is used to keep the tree short
            if (rank[x] > rank[y]) { p[y] = x; setSize[x] += setSize[y]; }
            else {
                p[x] = y; setSize[y] += setSize[x];
                if (rank[x] == rank[y]) rank[y]++;
            }
        }
    }

    int numDisjointSets() {		// # of disjoint sets
        return numSets;
    }

    int sizeOfSet(int i) {		// size of set
        return setSize[findSet(i)];
    }
};


#define MAXN 205000			// total # of prime numbers
#define MAXP 100100		// highest number to test prime

int prime[MAXN];		// prime numbers: 2, 3, 5 ...
int lp[MAXP];		// lp[n] = n if n is prime; otherwise smallest prime factor of the number
int phi[MAXP];			// phii function

class prime_class {
public:
    long top;

    prime_class() {			// generate all prime under MAXP
        int i, i2, j;

        top = 0;
        lp[0] = 0;
        lp[1] = 1;
        for (i = 2; i < MAXP; i++) lp[i] = 0;

        top = 0;
        for (i = 2; i < MAXP; ++i) {
            if (lp[i] == 0) {
                lp[i] = i;
                prime[top++] = i;
            }
            for (j = 0; (j < top) && (prime[j] <= lp[i]) && (i * prime[j] < MAXP); ++j)
                lp[i * prime[j]] = prime[j];
        }
    }

    bool isprime(long long key)
    {
        if (key < MAXP)	return (lp[key] == key) && (key >= 2);
        else {
            int i;
            for (i = 0; (i < top) && (prime[i] * prime[i] <= key); i++)
                if (key % prime[i] == 0) return false;
            return true;
        }
    }

    unordered_map<int, int> factorize(int key) {
        unordered_map<int, int> ans;

        while (lp[key] != key) {
            ans[lp[key]]++;
            key /= lp[key];
        }
        if (key > 1) ans[key]++;

        return ans;
    }

    vector<int> mobius(int n) {     // generate mobius function of size n
        int i, j, k, ct, curr, cct, x, last;
        vector<int> mobius(n + 1);
        for (i = 1; i <= n; i++) {
            curr = i; ct = 0; last = -1;

            while (lp[curr] != curr) {
                x = lp[curr];
                if (x != last) {
                    cct = 1;
                    last = x;
                    ct++;
                }
                else {
                    if (++cct >= 2) {
                        mobius[i] = 0;
                        goto outer;
                    }

                }
                curr /= lp[curr];
            }
            if (curr > 1) {
                x = curr;
                if (x != last) {
                    cct = 1;
                    last = x;
                    ct++;
                }
                else {
                    if (++cct >= 2) {
                        mobius[i] = 0;
                        goto outer;
                    }

                }
            }

            if (ct % 2 == 0) mobius[i] = 1;
            else mobius[i] = -1;

        outer:;
        }

        return mobius;
    }

    int get_phi(int key) {	// calculate Euler's totient function, also known as phi-function
        int ans = key, last = 0;

        while (lp[key] != key) {
            if (lp[key] != last) {
                last = lp[key];
                ans -= ans / last;
            }
            key /= lp[key];
        }
        if ((key > 1) && (key != last)) ans -= ans / key;

        return ans;
    }

    void calc_all_phi(int n) {
        int i, j, k;
        for (int i = 1; i < n; i++) phi[i] = i;
        for (int i = 2; i < n; i++) {
            if (phi[i] == i) {
                for (int j = i; j < n; j += i) {
                    phi[j] /= i;
                    phi[j] *= i - 1;
                }
            }
        }
    }

    vector<pair<long long, long long>> factorize_full(long long key) {		// can be used to factorize numbers >= MAXP
        vector<pair<long long, long long>> ans;

        long i, ct, sq = sqrt(key) + 10;

        for (i = 0; (i < top) && (prime[i] <= sq); i++)
            if (key % prime[i] == 0) {
                ct = 0;
                while (key % prime[i] == 0) {
                    ct++;
                    key /= prime[i];
                }
                ans.push_back({ prime[i], ct });
            }
        if (key > 1) {
            ans.push_back({ key, 1 });
        }
        return ans;
    }

    void generate_divisors(int step, int v, vector<pair<int, int>>& fp, vector<int>& ans) {
        if (step < fp.size()) {
            generate_divisors(step + 1, v, fp, ans);
            for (int i = 1; i <= fp[step].second; i++) {
                v *= fp[step].first;
                generate_divisors(step + 1, v, fp, ans);
            }
        }
        else ans.push_back(v);
    }

    void generate_divisors_full(long long step, long long v, vector<pair<long long, long long>>& fp, vector<long long>& ans) {
        if (step < fp.size()) {
            generate_divisors_full(step + 1, v, fp, ans);
            for (int i = 1; i <= fp[step].second; i++) {
                v *= fp[step].first;
                generate_divisors_full(step + 1, v, fp, ans);
            }
        }
        else ans.push_back(v);
    }

    vector<int> get_divisors(int key) {
        unordered_map<int, int> f = factorize(key);
        int n = f.size();
        vector<pair<int, int>> fp;
        for (auto p : f) fp.push_back(p);
        vector<int> ans;
        generate_divisors(0, 1, fp, ans);
        return ans;
    }

    vector<long long> get_divisors_full(long long key) {
        vector<pair<long long, long long>> f = factorize_full(key);
        int n = f.size();
        vector<pair<long long, long long>> fp;
        for (auto p : f) fp.push_back(p);
        vector<long long> ans;
        generate_divisors_full(0, 1, fp, ans);
        return ans;
    }


    long long get_divisors_count(long long key) {
        vector<pair<long long, long long>> f = factorize_full(key);
        long long ans = 1;
        for (auto p : f) ans *= (p.second + 1);
        return ans;
    }

};


long long mul_inv(long long a, long long b)
{
    long long b0 = b, t, q;
    long long x0 = 0, x1 = 1;
    if (b == 1) return 1;
    while (a > 1) {
        q = a / b;
        t = b, b = a % b, a = t;
        t = x0, x0 = x1 - q * x0, x1 = t;
    }
    if (x1 < 0) x1 += b0;
    return x1;
}

long long division(long long a, long long b, long long p) {		// (a / b) mod p = ((a mod p) * (b^(-1) mod p)) mod p
    long long ans, inv;
    inv = mul_inv(b, p);
    ans = ((a % p) * inv) % p;
    return ans;
}


#define MP make_pair
#define PB push_back
#define F first
#define S second
#define LB lower_bound
#define UB upper_bound

#define SZ(x) ((int)x.size())
#define LEN(x) ((int)x.length())
#define ALL(x) begin(x), end(x)
#define RSZ resize
#define ASS assign
#define REV(x) reverse(x.begin(), x.end());

#define MAX(x) *max_element(ALL(x))
#define MIN(x) *min_element(ALL(x))
#define FOR(i, n) for (int i = 0; i < n; i++) 
#define FOR1(i, n) for (int i = 1; i <= n; i++) 
#define SORT(x) sort(x.begin(), x.end())
#define RSORT(x) sort(x.rbegin(), x.rend())
#define SUM(x) accumulate(x.begin(), x.end(), 0LL)


#define IN(x) cin >> x;
#define OUT(x) cout << x << "\n";
#define INV(x, n) FOR(iiii, n) { cin >> x[iiii]; }
#define INV1(x, n) FOR1(iiii, n) { cin >> x[iiii]; }
#define OUTV(x, n) { FOR(iiii, n) { cout << x[iiii] << " "; } cout << "\n"; }
#define OUTV1(x, n) { FOR1(iiii, n) { cout << x[iiii] << " "; } cout << "\n"; }
#define OUTYN(x) { if (x) cout << "YES\n"; else cout << "NO\n"; }
#define OUTyn(x) { if (x) cout << "Yes\n"; else cout << "No\n"; }


#define MOD7 1000000007
#define MOD9 1000000009
#define MOD3 998244353



int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    LL t, n, q, l, r, i, j, k, ans, x;
    string s;

    cin >> t;
    while (t--) {
        cin >> n >> q >> s;
        
        fenwick_tree<LL> ft(n + 2);
        FOR1(i, n) {
            if (i + 2 <= n) {
                if ((s[i - 1] == s[i]) || (s[i] == s[i + 1]) || (s[i - 1] == s[i + 1])) ft.update(i, 1);
            }
        }

        while (q--) {
            cin >> l >> r;
            if (l + 2 > r) ans = 0;
            else ans = ft.query_full(l, r - 2);

            OUTYN(ans > 0);
        }
    }



    return 0;
}

Rich Substrings CodeChef Solution in PYTH 3

for tea in range(int(input())):
    n,q = map(int,input().split())
    s = list(input())
    if n <= 2:
        for qq in range(q):
            input()
            print("NO")
        continue
    
    gud = []
    for i in range(n-2):
        if len(set([s[i],s[i+1],s[i+2]])) < 3: gud.append(i)
    
    stuff = dict()
    ind = 0
    for i in range(n):
        stuff[i] = ind
        if ind < len(gud) and i >= gud[ind]:
            ind += 1
        
    
    for qq in range(q):
        l,r = [int(x)-1 for x in input().split()]
        r -= 2
        if l > r:
            print("NO")
            continue
        #binary search go brrrrrrr
        if stuff[l] == stuff[r+1]: print("NO")
        else: print("YES")

Rich Substrings CodeChef Solution in C

#include <stdio.h>
char s[100001];
int a[100001],b[100001];
int main(void) {
	// your code goes here
	int t;
	scanf("%d",&t);
	while(t--)
	{
	    int n,q;
	    scanf("%d",&n);
	    scanf("%d",&q);
	   
	    int i,j;
	    scanf(" %s",s);
	    
	    for(i=0;i<n;i++){
	        a[i]=0;
	        b[i]=0;
	    }
	    
	   for(i=2;i<n;i++){
	    			
	    		if(s[i]==s[i-1]||s[i]==s[i-2]||s[i-1]==s[i-2])
	    			a[i]=1;
	    		if(i==2)
	    			b[2]=a[2];
	    		if(i>2)
	    			b[i]=b[i-1]+a[i];
	    	}
//for(i=0;i<n;i++){printf("%d\n",b[i]);}
	    int l,r;
	    for(i=0;i<q;i++)
	    {
	        scanf("%d%d",&l,&r);
	        if(r-l+1<3)
	         printf("NO\n");
	    else if( (b[r-1]-b[l])>=1)
            printf("YES\n");
                else
	        printf("NO\n");
	    }
	}
	return 0;
}

Rich Substrings CodeChef Solution in JAVA

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Random;
import java.util.StringTokenizer;

/*
aba
bac
aca

abacabaca
 */
public class Main {

	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		int t = sc.nextInt();
		for (int i = 0; i < t; i++) {
			int n = sc.nextInt();
			int q = sc.nextInt();
			String s = sc.next();
			int[][] req = new int[q][2];
			for (int j = 0; j < q; j++) {
				req[j] = sc.readArrayInt(2);
			}
			solve(s, req);
		}
	}

	public static void solve(String s, int[][] q) {
		int n = s.length();
		int[] p = new int[n + 1];
		for (int i = 0; i < n - 2; i++) {
			p[i+1] = p[i];
			if (s.charAt(i) == s.charAt(i + 1) || s.charAt(i) == s.charAt(i + 2) || s.charAt(i + 1) == s.charAt(i + 2)) {
				p[i + 1]++;
			}
		}
		for (int[] ints : q) {
			int l = ints[0]-1;
			int r = ints[1]-1;
			if (r-l+1<3){
				System.out.println("NO");
				continue;
			}
			int val = p[r -1] - p[l];
			if (val > 0) {
				System.out.println("YES");
			} else {
				System.out.println("NO");
			}
		}
	}

	public static final void swap(int[] a, int i, int j) {
		int t = a[i];
		a[i] = a[j];
		a[j] = t;
	}

	private static void shuffleArray(int[] array) {
		int index;
		Random random = new Random();
		for (int i = array.length - 1; i > 0; i--) {
			index = random.nextInt(i + 1);
			if (index != i) {
				array[index] ^= array[i];
				array[i] ^= array[index];
				array[index] ^= array[i];
			}
		}
	}

	static class SegmentTree {

		private Node[] heap;
		private int[] array;
		private int size;

		/**
		 * Time-Complexity:  O(n*log(n))
		 *
		 * @param array the Initialization array
		 */
		SegmentTree(int[] array) {
			this.array = Arrays.copyOf(array, array.length);
			//The max size of this array is about 2 * 2 ^ log2(n) + 1
			size = (int) (2 * Math.pow(2.0, Math.floor((Math.log((double) array.length) / Math.log(2.0)) + 1)));
			heap = new Node[size];
			build(1, 0, array.length);
		}

		public int size() {
			return array.length;
		}

		//Initialize the Nodes of the Segment tree
		private void build(int v, int from, int size) {
			heap[v] = new Node();
			heap[v].from = from;
			heap[v].to = from + size - 1;

			if (size == 1) {
				heap[v].sum = array[from];
				heap[v].min = array[from];
			} else {
				//Build childs
				build(2 * v, from, size / 2);
				build(2 * v + 1, from + size / 2, size - size / 2);

				heap[v].sum = heap[2 * v].sum + heap[2 * v + 1].sum;
				//min = min of the children
				heap[v].min = Math.min(heap[2 * v].min, heap[2 * v + 1].min);
			}
		}

		
		public int rsq(int from, int to) {
			return rsq(1, from, to);
		}

		private int rsq(int v, int from, int to) {
			Node n = heap[v];

			//If you did a range update that contained this node, you can infer the Sum without going down the tree
			if (n.pendingVal != null && contains(n.from, n.to, from, to)) {
				return (to - from + 1) * n.pendingVal;
			}

			if (contains(from, to, n.from, n.to)) {
				return heap[v].sum;
			}

			if (intersects(from, to, n.from, n.to)) {
				propagate(v);
				int leftSum = rsq(2 * v, from, to);
				int rightSum = rsq(2 * v + 1, from, to);

				return leftSum + rightSum;
			}

			return 0;
		}

		
		public int rMinQ(int from, int to) {
			return rMinQ(1, from, to);
		}

		private int rMinQ(int v, int from, int to) {
			Node n = heap[v];

			//If you did a range update that contained this node, you can infer the Min value without going down the tree
			if (n.pendingVal != null && contains(n.from, n.to, from, to)) {
				return n.pendingVal;
			}

			if (contains(from, to, n.from, n.to)) {
				return heap[v].min;
			}

			if (intersects(from, to, n.from, n.to)) {
				propagate(v);
				int leftMin = rMinQ(2 * v, from, to);
				int rightMin = rMinQ(2 * v + 1, from, to);

				return Math.max(leftMin, rightMin);
			}

			return Integer.MIN_VALUE;
		}

		//Propagate temporal values to children
		private void propagate(int v) {
			Node n = heap[v];

			if (n.pendingVal != null) {
				change(heap[2 * v], n.pendingVal);
				change(heap[2 * v + 1], n.pendingVal);
				n.pendingVal = null; //unset the pending propagation value
			}
		}

		//Save the temporal values that will be propagated lazily
		private void change(Node n, int value) {
			n.pendingVal = value;
			n.sum = n.size() * value;
			n.min = value;
			array[n.from] = value;

		}

		//Test if the range1 contains range2
		private boolean contains(int from1, int to1, int from2, int to2) {
			return from2 >= from1 && to2 <= to1;
		}

		//check inclusive intersection, test if range1[from1, to1] intersects range2[from2, to2]
		private boolean intersects(int from1, int to1, int from2, int to2) {
			return from1 <= from2 && to1 >= from2   //  (.[..)..] or (.[...]..)
					|| from1 >= from2 && from1 <= to2; // [.(..]..) or [..(..)..
		}

		//The Node class represents a partition range of the array.
		static class Node {
			int sum;
			int min;
			//Here We store the value that will be propagated lazily
			Integer pendingVal = null;
			int from;
			int to;

			int size() {
				return to - from + 1;
			}

		}
	}

	static class FastScanner {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");

		String next() {
			while (!st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				}
				catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long[] readArrayLong(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextLong();
			}
			return a;
		}

		int[] readArrayInt(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = nextInt();
			}
			return a;
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}
	}

	static class BIT {

		// The size of the array holding the Fenwick tree values
		final int N;

		// This array contains the Fenwick tree ranges
		private long[] tree;

		// Create an empty Fenwick Tree with 'sz' parameter zero based.
		public BIT(int sz) {
			tree = new long[(N = sz + 1)];
		}

		// Construct a Fenwick tree with an initial set of values.
		// The 'values' array MUST BE ONE BASED meaning values[0]
		// does not get used, O(n) construction.
		public BIT(long[] values) {

			if (values == null) {
				throw new IllegalArgumentException("Values array cannot be null!");
			}

			N = values.length;
			values[0] = 0L;

			// Make a clone of the values array since we manipulate
			// the array in place destroying all its original content.
			tree = values.clone();

			for (int i = 1; i < N; i++) {
				int parent = i + lsb(i);
				if (parent < N) {
					tree[parent] += tree[i];
				}
			}
		}

		// Returns the value of the least significant bit (LSB)
		// lsb(108) = lsb(0b1101100) = 0b100 = 4
		// lsb(104) = lsb(0b1101000) = 0b1000 = 8
		// lsb(96) = lsb(0b1100000) = 0b100000 = 32
		// lsb(64) = lsb(0b1000000) = 0b1000000 = 64
		private static int lsb(int i) {

			// Isolates the lowest one bit value
			return i & -i;

			// An alternative method is to use the Java's built in method
			// return Integer.lowestOneBit(i);

		}

		// Computes the prefix sum from [1, i], O(log(n))
		private long prefixSum(int i) {
			long sum = 0L;
			while (i != 0) {
				sum += tree[i];
				i &= ~lsb(i); // Equivalently, i -= lsb(i);
			}
			return sum;
		}

		// Returns the sum of the interval [left, right], O(log(n))
		public long sum(int left, int right) {
			if (right < left) {
				throw new IllegalArgumentException("Make sure right >= left");
			}
			return prefixSum(right) - prefixSum(left - 1);
		}

		// Get the value at index i
		public long get(int i) {
			return sum(i, i);
		}

		// Add 'v' to index 'i', O(log(n))
		public void add(int i, long v) {
			while (i < N) {
				tree[i] += v;
				i += lsb(i);
			}
		}

		// Set index i to be equal to v, O(log(n))
		public void set(int i, long v) {
			add(i, v - sum(i, i));
		}

		@Override
		public String toString() {
			return java.util.Arrays.toString(tree);
		}
	}

	static class SparseTable {
		private final int[][] table;
		private final int[] pow;
		private final int[] a;
		private final int MAX_LOG = 20;
		private final int MAXN = (int) 1e5;

		public SparseTable(int[] a) {
			int n = a.length;
			this.a = a;
			this.pow = new int[MAXN + 1];
			buildPows();
			this.table = new int[n][MAX_LOG + 1];
			buildTable();
		}

		private void buildPows() {
			for (int i = 2; i < MAXN + 1; i++) {
				pow[i] = pow[i / 2] + 1;
			}
		}

		private void buildTable() {
			int n = a.length;
			for (int i = 0; i <= MAX_LOG; i++) {
				int length = 1 << i;
				for (int j = 0; j + length <= n; j++) {
					if (i == 0) {
						table[j][i] = a[j];
					} else {
						table[j][i] = Math.min(table[j][i - 1], table[j + (length / 2)][i - 1]);
					}
				}
			}
		}

		public int query(int l, int r) {
			int max = pow[r - l + 1];
			int length = 1 << max;
			return Math.min(table[l][max], table[r - length + 1][max]);
		}
	}
}

Rich Substrings CodeChef Solution in PYPY 3

from sys import stdin
input=stdin.readline

def sparsetable():

    for j in range(1,20):

        for i in range(n):
            if(i + (1 << (j-1)) >= n):continue
            
            xor[i][j]=xor[i][j-1] | xor[i + (1 << (j-1))][j-1]

def queries(l,r):

    if(l > r):return 'NO'

    x=False
    size=(r - l + 1)
    for i in range(20-1,-1,-1):

        if(size >> i & 1):
            x |= xor[l][i]

            l+=(1 << i)

    if(x):return 'YES'
    else:return 'NO'


for T in range(int(input())):
    n,q=map(int,input().split())

    s=input()

    ans=[False]*(n)

    for i in range(n-2):

        c=0
        if(s[i]==s[i+1]):c+=1
        if(s[i]==s[i+2]):c+=1
        if(s[i+1]==s[i+2]):c+=1

        if(c!=0):ans[i]=True


    xor=[[False for i in range(20)] for j in range(n + 1)]

    for i in range(n):xor[i][0]=ans[i]
    
    sparsetable()

    for i in range(q):
        l,r=map(int,input().split())
        l-=1
        r-=3

        print(queries(l,r))
    

Rich Substrings CodeChef Solution in PYTH

t = int(raw_input())
for i in range(t):
	st = raw_input().split()
	N = int(st[0])
	Q = int(st[1])
	A = [0 for x in range(N+2)]
	n = 0
	st = raw_input().strip()
	for p in range(3,N+1):
		if (st[p-1] == st[p-2]) or (st[p-1] == st[p-3]) or (st[p-2] == st[p-3]):
			n += 1
		# endif
		A[p] = n
	# endfor p
	for k in range(Q):
		st = raw_input().split()
		L = int(st[0])
		R = int(st[1])
		if (A[L] < A[R]) and (A[L+1] < A[R]):
			print 'YES'
		else:
			print 'NO'
		# endif
	# endfor k
# endfor i

Rich Substrings CodeChef Solution in C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		var sb = new StringBuilder();
		for(;T>0;T--){
			int N, Q;
			var d = ria();
			N = d[0]; Q = d[1];
			String S = rs();
			int[] L,R;
			L = new int[Q];
			R = new int[Q];
			for(int i=0;i<Q;i++){
				d = ria();
				L[i] = d[0] - 1;
				R[i] = d[1];
			}
			
			int[] Rich = new int[N];
			for(int i=0;i+3-1<N;i++){
				int[] cnt = new int[26];
				cnt[S[i] - 'a']++;
				cnt[S[i+1] - 'a']++;
				cnt[S[i+2] - 'a']++;
				for(int j=0;j<26;j++) if(cnt[j] >= 2) Rich[i] = 1;
			}
			int[] Sum = new int[N + 1];
			for(int i=0;i<N;i++) Sum[i + 1] = Sum[i] + Rich[i];
			
			for(int i=0;i<Q;i++){
				int l = L[i], r = R[i];
				if(r - 2 < 0){
					sb.AppendLine("NO");
					continue;
				}
				int sr = Sum[r - 3 + 1];
				int sl = Sum[l];
				if(r - l >= 3 && sr - sl > 0){
					sb.AppendLine("YES");
				} else {
					sb.AppendLine("NO");
				}
				
			}
			
		}
		Console.Write(sb.ToString());
	}
	int T;
	public Sol(){
		T = ri();
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}
Rich Substrings CodeChef Solution Review:

In our experience, we suggest you solve this Rich Substrings CodeChef Solution and gain some new skills from Professionals completely free and we assure you will be worth it.

If you are stuck anywhere between any coding problem, just visit Queslers to get the Rich Substrings CodeChef Solution.

Find on CodeChef

Conclusion:

I hope this Rich Substrings CodeChef Solution would be useful for you to learn something new from this problem. If it helped you then don’t forget to bookmark our site for more Coding Solutions.

This Problem is intended for audiences of all experiences who are interested in learning about Programming Language in a business context; there are no prerequisites.

Keep Learning!

More Coding Solutions >>

Cognitive Class Answer

CodeChef Solution

Microsoft Learn

Leave a Reply

Your email address will not be published. Required fields are marked *