Problem:
ほぼ周期文字列
文字列
S
が与えられる。この文字列
S
に対し、
Q
個のクエリに答えよ。
i
番目のクエリでは、
S[l_i,\ r_i]
から1文字まで変えてよいとき、
S[l_i,\ r_i]
を周期
t_i
の文字列にできるかどうかを判定せよ。
S[l,\ r]
は文字列
S
の
l
文字目から
r
文字目までの部分文字列を表す。
文字列
W
が周期
t
の文字列であるとは、
i\ =\ 1,\2,\... ,\ |W| − t
に対し、
W_{i} = W_{i+t}
となることとする。
Constraints
1  ≤  |S|  ≤  10^5
1  ≤  Q  ≤  10^5
1  ≤  l_i  ≤  r_i  ≤  |S|
1  ≤  t_i  ≤  r_i − l_i+1
S
はアルファベットの小文字のみからなる
Input Format
入力は以下の形式で標準入力から与えられる。
S
Q
l_1
r_1
t_1
...
l_Q
r_Q
t_Q
Output Format
Q
行にわたって出力せよ。
i
行目には、
i
番目のクエリの答えを
Yes
または
No
で出力せよ。
Sample Input 1
abcabcaxcabc
4
1 9 3
8 12 3
1 4 2
2 3 2
Sample Output 1
Yes
Yes
No
Yes
Sample Input 2
isuruu
4
3 6 1
3 6 2
3 6 3
2 4 1
Sample Output 2
Yes
Yes
Yes
No

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]

    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]

    return get(R - L) + L;
}
}; // namespace Random

/**
 * @brief Random
 */

struct RollingHash {
    using ull = unsigned long long;
    const ull MOD = 0x1fffffffffffffff;
    const ull base;
    vector<ull> hashed, power;

    static constexpr ull mask(ll a) { return (1ULL << a) - 1; }

    inline ull mul(ull a, ull b) const {
        __uint128_t ans = __uint128_t(a) * b;
        ans = (ans >> 61) + (ans & MOD);
        if (ans >= MOD)
            ans -= MOD;
        return ans;
    }

    static inline ull genbase() { return Random::get(ull(0x1fffffffffffffff)); }
    RollingHash() = default;

    RollingHash(const string &s, ull base) : base(base) {
        ll n = s.size();
        hashed.assign(n + 1, 0);
        power.assign(n + 1, 0);
        power[0] = 1;
        for (ll i = 0; i < n; i++) {
            power[i + 1] = mul(power[i], base);
            hashed[i + 1] = mul(hashed[i], base) + s[i];
            if (hashed[i + 1] >= MOD)
                hashed[i + 1] -= MOD;
        }
    }

    ull get(ll l, ll r) const {
        ull ret = hashed[r] + MOD - mul(hashed[l], power[r - l]);
        if (ret >= MOD)
            ret -= MOD;
        return ret;
    }

    ull connect(ull h1, ull h2, ll h2len) const {
        ull ret = mul(h1, power[h2len]) + h2;
        if (ret >= MOD)
            ret -= MOD;
        return ret;
    }

    void connect(const string &s) {
        ll n = hashed.size() - 1, m = s.size();
        hashed.resize(n + m + 1);
        power.resize(n + m + 1);
        for (ll i = n; i < n + m; i++) {
            power[i + 1] = mul(power[i], base);
            hashed[i + 1] = mul(hashed[i], base) + s[i - n];
            if (hashed[i + 1] >= MOD)
                hashed[i + 1] -= MOD;
        }
    }

    ll LCP(const RollingHash &b, ll l1, ll r1, ll l2, ll r2) {
        ll len = min(r1 - l1, r2 - l2);
        ll low = -1, high = len + 1;
        while (high - low > 1) {
            ll mid = (low + high) / 2;
            if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
                low = mid;
            else
                high = mid;
        }
        return low;
    }
};

/**
 * @brief Rolling Hash
 */

int main() {
    string S;
    cin >> S;
    ull base = RollingHash::genbase();
    RollingHash H(S,1000);
    int Q;
    cin >> Q;
    while(Q--) {
        int L, R, T;
        cin >> L >> R >> T;
        L--;
        if (H.get(L,R-T) == H.get(L+T,R)) {
            cout << "Yes" << endl;
            continue;
        }
        int X = H.LCP(H,L,R-T,L+T,R);
        int Left = L+X, Right = L+X+T;
        auto getChangedHash = [&](int l, int r, int from, int to) -> ull {
            ull Cur = H.get(l,r);
            if (l <= from && from < r) {
                Cur += H.MOD - H.mul((ull)S[from],H.power[r-1-from]);
                if (Cur >= H.MOD) Cur -= H.MOD;
                Cur += H.mul((ull)S[to],H.power[r-1-from]);
                if (Cur >= H.MOD) Cur -= H.MOD;
            }
            return Cur;
        };
        bool check = false;
        if (getChangedHash(L,R-T,Left,Right) == getChangedHash(L+T,R,Left,Right)) check = true;
        if (getChangedHash(L,R-T,Right,Left) == getChangedHash(L+T,R,Right,Left)) check = true;
        cout << (check ? "Yes" : "No") << endl;
    }
}
accuracy: 1
time_ms: 130
memory_kb: 5008
final_rank: 2

code_snippet: #include <iostream>
#include <string>
#include <algorithm>
using namespace std;

struct Data {
	pair<long long, long long> key;
	pair<int, int> val;
};

bool operator<(const Data &a1, const Data &a2) {
	if (a1.key < a2.key) return true;
	if (a1.key > a2.key) return false;
	if (a1.val < a2.val) return true;
	return false;
}

bool operator==(const Data &a1, const Data &a2) {
	if (a1.key == a2.key && a1.val == a2.val) return true;
	return false;
}

const long long mod1 = 2000000011;
const long long mod2 = 2147483647;
const long long BASE = 233;
string S;
long long N, Q, L[100009], R[100009], T[100009];
long long Hash1[100009], Pow1[100009];
long long Hash2[100009], Pow2[100009];
Data Map[5200009]; int DataCount = 0;

long long modpow(long long a, long long b, long long m) {
	long long p = 1, q = a;
	for (int i = 0; i < 60; i++) {
		if ((b / (1LL << i)) % 2LL == 1) { p *= q; p %= m; }
		q *= q; q %= m;
	}
	return p;
}

long long Division(long long a, long long b, long long m) {
	return (1LL * a * modpow(b, m - 2, m)) % m;
}

void Initialize() {
	Pow1[0] = 1; Pow2[0] = 1;
	for (int i = 1; i <= N; i++) Pow1[i] = (1LL * BASE * Pow1[i - 1]) % mod1;
	for (int i = 1; i <= N; i++) Pow2[i] = (1LL * BASE * Pow2[i - 1]) % mod2;
	for (int i = 1; i <= N; i++) {
		long long val = (long long)(S[i - 1] - 'a') + 1;
		Hash1[i] = (1LL * BASE * Hash1[i - 1] + val) % mod1;
		Hash2[i] = (1LL * BASE * Hash2[i - 1] + val) % mod2;
	}
}

pair<long long, long long> GetHash(int cl, int cr) {
	long long val1 = Hash1[cr] - Pow1[cr - cl + 1] * Hash1[cl - 1];
	long long val2 = Hash2[cr] - Pow2[cr - cl + 1] * Hash2[cl - 1];
	val1 = (val1 + mod1 * mod1) % mod1;
	val2 = (val2 + mod2 * mod2) % mod2;
	return make_pair(val1, val2);
}

pair<int, int> Search(pair<long long, long long> Diff) {
	Data tmp; tmp.key = Diff; tmp.val = make_pair(-1000, -1000);
	int pos1 = lower_bound(Map, Map + DataCount, tmp) - Map;
	if (pos1 < DataCount && Map[pos1].key == Diff) return Map[pos1].val;
	return make_pair(-1, -1);
}

int main() {
	// Input
	cin >> S; N = S.size();
	cin >> Q;
	for (int i = 1; i <= Q; i++) cin >> L[i] >> R[i] >> T[i];
	
	// Get Hash Value
	Initialize();
	for (int i = 0; i <= N; i++) {
		for (int j = -25; j <= 25; j++) {
			if (j == 0) continue;
			long long val1 = (1LL * j * Pow1[i] + mod1 * mod1) % mod1;
			long long val2 = (1LL * j * Pow2[i] + mod2 * mod2) % mod2;
			Map[DataCount].key = make_pair(val1, val2);
			Map[DataCount].val = make_pair(i, j);
			DataCount += 1;
		}
	}
	sort(Map, Map + DataCount);
	
	// Answer Query
	for (int i = 1; i <= Q; i++) {
		pair<long long, long long> Value1 = GetHash(L[i], R[i] - T[i]);
		pair<long long, long long> Value2 = GetHash(L[i] + T[i], R[i]);
		pair<long long, long long> Diff;
		Diff.first = (Value1.first - Value2.first + mod1) % mod1;
		Diff.second = (Value1.second - Value2.second + mod2) % mod2;
		if (Diff == make_pair(0LL, 0LL)) {
			cout << "Yes" << endl;
			continue;
		}
		
		// First Chance
		int cl = T[i], cr = (R[i] - L[i]) - 2 * T[i];
		pair<int, int> val1 = Search(Diff);
		if (val1.first != -1 && (val1.first < cl || cr < val1.first)) {
			cout << "Yes" << endl;
			continue;
		}
		
		// Second Chance
		long long keisuu1 = (Pow1[T[i]] + mod1 - 1LL) % mod1;
		long long keisuu2 = (Pow2[T[i]] + mod2 - 1LL) % mod2;
		Diff.first = Division(Diff.first, keisuu1, mod1);
		Diff.second = Division(Diff.second, keisuu2, mod2);
		pair<int, int> val2 = Search(Diff);
		if (val2.first != -1 && val2.first <= cr) {
			cout << "Yes" << endl;
			continue;
		}
		
		// Case of :(
		cout << "No" << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 710
memory_kb: 128872
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

struct SuffixArray {
  string s;
  vector<int> sa;
  vector<int> rank;
  vector<int> lcp;
  explicit SuffixArray(string s) : s(s) {
    int n = s.size();
    sa.resize(n + 1);
    rank.resize(n + 1);
    vector<int> tmp(n + 1);
    for (int i = 0; i <= n; i++) {
      rank[i] = (i < n) ? s[i] : -1;
      sa[i] = i;
    }
    for (int k = 1; k <= n; k *= 2) {
      auto compare_sa = [&](const int &i, const int &j) {
        if (rank[i] != rank[j])
          return rank[i] < rank[j];
        else {
          int ri = (i + k <= s.size()) ? rank[i + k] : -1;
          int rj = (j + k <= s.size()) ? rank[j + k] : -1;
          return ri < rj;
        }
      };
      sort(sa.begin(), sa.end(), compare_sa);
      tmp[sa[0]] = 0;
      for (int i = 1; i <= n; i++)
        tmp[sa[i]] = tmp[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
      for (int i = 0; i <= n; i++) rank[i] = tmp[i];
    }
  }
  size_t size() const { return s.size(); }
  int operator[](int id) const { return sa[id]; }
  bool contain(string t) {
    int l = 0, r = s.size() + 1;
    while (r - l > 1) {
      int mid = (l + r) / 2;
      if (s.compare(sa[mid], t.size(), t) < 0) {
        l = mid;
      } else {
        r = mid;
      }
    }
    return s.compare(sa[r], t.size(), t) == 0;
  }
};

struct LongestCommonPrefix {
  const SuffixArray &sa;
  vector<int> lcp, rank;
  explicit LongestCommonPrefix(const SuffixArray &sa) : sa(sa) {
    int n = sa.size();
    lcp.resize(sa.size() + 1);
    rank.resize(sa.size() + 1);
    for (int i = 0; i <= sa.size(); i++) { rank[sa[i]] = i; }
    int h = 0;
    lcp[0] = 0;
    for (int i = 0; i < sa.size(); i++) {
      int j = sa[rank[i] - 1];
      if (h > 0) h--;
      for (; i + h < n && j + h < n; h++)
        if (sa.s[i + h] != sa.s[j + h]) break;
      lcp[rank[i] - 1] = h;
    }
  }
  int operator[](int id) const {
    assert(id >= 0 && id < lcp.size());
    return lcp[id];
  }
};

template <class D>
struct SegmentTree {
  using DMerger = function<D(D, D)>;
  int length;
  vector<D> seg;
  const DMerger dm;
  const D d_unit;

  SegmentTree() {}
  SegmentTree(int n, const DMerger dm, const D &d_unit)
      : dm(dm), d_unit(d_unit) {
    length = 1;
    while (length < n) length <<= 1;
    seg.assign(2 * length, d_unit);
  }
  SegmentTree(vector<D> vec, const DMerger dm, const D &d_unit)
      : dm(dm), d_unit(d_unit) {
    length = 1;
    while (length < vec.size()) length <<= 1;
    seg.assign(2 * length, d_unit);
    for (int i = 0; i < vec.size(); i++) seg[length - 1 + i] = vec[i];
    for (int i = length - 2; i >= 0; i--)
      seg[i] = dm(seg[i * 2 + 1], seg[i * 2 + 2]);
  }

  void update(int k, D x) {
    k += length - 1;
    seg[k] = x;
    while (k) {
      k = (k - 1) / 2;
      seg[k] = dm(seg[k * 2 + 1], seg[k * 2 + 2]);
    }
  }

  D query(int a, int b, int k, int l, int r) const {
    if (r <= a || b <= l) {
      return d_unit;
    } else if (a <= l && r <= b) {
      return seg[k];
    } else {
      D lch = query(a, b, k * 2 + 1, l, (l + r) / 2);
      D rch = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return dm(lch, rch);
    }
  }
  D query(int a, int b) const { return query(a, b, 0, 0, length); }
  D get_point(int x) { return seg[length - 1 + x]; }
};

struct RMQFromLCP {
  const LongestCommonPrefix &lcp;
  SegmentTree<int> seg;
  explicit RMQFromLCP(const LongestCommonPrefix &lcp)
      : lcp(lcp), seg(
                      lcp.lcp, [](int a, int b) { return std::min(a, b); },
                      std::numeric_limits<int>::max()) {}
  int getLongestCommonStringFrom(int s, int t) const {
    int L = std::min(lcp.rank[s], lcp.rank[t]);
    int R = std::max(lcp.rank[s], lcp.rank[t]);
    return seg.query(L, R);
  }
};

void solve() {
  string S;
  cin >> S;
  SuffixArray sa(S);
  LongestCommonPrefix lcp(sa);
  RMQFromLCP rmq(lcp);

  int Q;
  cin >> Q;
  for (int i = 0; i < Q; i++) {
    int l, r, t;
    cin >> l >> r >> t;
    if (t == r - l + 1) {
      cout << "Yes" << endl;
      continue;
    }

    l--;

    int common_len = rmq.getLongestCommonStringFrom(l, l + t);
    dmp(common_len);
    if (common_len >= r - l - t) {
      cout << "Yes" << endl;
      continue;
    }

    vector<int> fix_cand;
    fix_cand.push_back(l + common_len);
    fix_cand.push_back(l + t + common_len);
    dmp(fix_cand);

    bool found = false;
    for (int cand : fix_cand) {
      if (cand < l + t) {
        if (rmq.getLongestCommonStringFrom(cand + 1, cand + 1 + t) >=
            r - l - t - common_len - 1) {
          found = true;
          break;
        }
      }
      if (cand >= r - t) {
        if (rmq.getLongestCommonStringFrom(cand + 1, cand + 1 - t) >=
            r - l - t - common_len - 1) {
          found = true;
          break;
        }
      }
      if (l + t <= cand && cand < r - t) {
        if (S[cand - t] == S[cand + t]) {
          int common_len_middle =
              rmq.getLongestCommonStringFrom(cand - t + 1, cand + 1);
          if (common_len_middle >= t - 1) {
            if (rmq.getLongestCommonStringFrom(cand + 1, cand + 1 + t) >=
                r - l - t - common_len - 2 - common_len_middle) {
              found = true;
              break;
            }
          }
        }
      }
    }

    if (found)
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }
  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 6440
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

struct SuffixArray {
  string s;
  vector<int> sa;
  vector<int> rank;
  vector<int> lcp;
  explicit SuffixArray(string s) : s(s) {
    int n = s.size();
    sa.resize(n + 1);
    rank.resize(n + 1);
    vector<int> tmp(n + 1);
    for (int i = 0; i <= n; i++) {
      rank[i] = (i < n) ? s[i] : -1;
      sa[i] = i;
    }
    for (int k = 1; k <= n; k *= 2) {
      auto compare_sa = [&](const int &i, const int &j) {
        if (rank[i] != rank[j])
          return rank[i] < rank[j];
        else {
          int ri = (i + k <= s.size()) ? rank[i + k] : -1;
          int rj = (j + k <= s.size()) ? rank[j + k] : -1;
          return ri < rj;
        }
      };
      sort(sa.begin(), sa.end(), compare_sa);
      tmp[sa[0]] = 0;
      for (int i = 1; i <= n; i++)
        tmp[sa[i]] = tmp[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
      for (int i = 0; i <= n; i++) rank[i] = tmp[i];
    }
  }
  size_t size() const { return s.size(); }
  int operator[](int id) const { return sa[id]; }
  bool contain(string t) {
    int l = 0, r = s.size() + 1;
    while (r - l > 1) {
      int mid = (l + r) / 2;
      if (s.compare(sa[mid], t.size(), t) < 0) {
        l = mid;
      } else {
        r = mid;
      }
    }
    return s.compare(sa[r], t.size(), t) == 0;
  }
};

template <class D>
struct SegmentTree {
  using DMerger = function<D(D, D)>;
  int length;
  vector<D> seg;
  const DMerger dm;
  const D d_unit;

  SegmentTree() {}
  SegmentTree(int n, const DMerger dm, const D &d_unit)
      : dm(dm), d_unit(d_unit) {
    length = 1;
    while (length < n) length <<= 1;
    seg.assign(2 * length, d_unit);
  }
  SegmentTree(vector<D> vec, const DMerger dm, const D &d_unit)
      : dm(dm), d_unit(d_unit) {
    length = 1;
    while (length < vec.size()) length <<= 1;
    seg.assign(2 * length, d_unit);
    for (int i = 0; i < vec.size(); i++) seg[length - 1 + i] = vec[i];
    for (int i = length - 2; i >= 0; i--)
      seg[i] = dm(seg[i * 2 + 1], seg[i * 2 + 2]);
  }

  void update(int k, D x) {
    k += length - 1;
    seg[k] = x;
    while (k) {
      k = (k - 1) / 2;
      seg[k] = dm(seg[k * 2 + 1], seg[k * 2 + 2]);
    }
  }

  D query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) {
      return d_unit;
    } else if (a <= l && r <= b) {
      return seg[k];
    } else {
      D lch = query(a, b, k * 2 + 1, l, (l + r) / 2);
      D rch = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return dm(lch, rch);
    }
  }
  D query(int a, int b) { return query(a, b, 0, 0, length); }
  D get_point(int x) { return seg[length - 1 + x]; }
};

template <class T>
SegmentTree<T> getRMQ(const vector<T> &vec) {
  return SegmentTree<T>(
      vec, [](T a, T b) { return min(a, b); }, std::numeric_limits<T>::max());
}

struct LongestCommonPrefix {
  const SuffixArray &sa;
  vector<int> lcp, rank;
  explicit LongestCommonPrefix(const SuffixArray &sa) : sa(sa) {
    int n = sa.size();
    lcp.resize(sa.size() + 1);
    rank.resize(sa.size() + 1);
    for (int i = 0; i <= sa.size(); i++) { rank[sa[i]] = i; }
    int h = 0;
    lcp[0] = 0;
    for (int i = 0; i < sa.size(); i++) {
      int j = sa[rank[i] - 1];
      if (h > 0) h--;
      for (; i + h < n && j + h < n; h++)
        if (sa.s[i + h] != sa.s[j + h]) break;
      lcp[rank[i] - 1] = h;
    }
  }
  int operator[](int id) const {
    assert(id >= 0 && id < lcp.size());
    return lcp[id];
  }
};

void solve() {
  string S;
  cin >> S;
  SuffixArray sa(S);
  LongestCommonPrefix lcp(sa);

  auto seg = getRMQ(lcp.lcp);
  for (int i = 0; i <= S.size(); i++) {
    dmp(i, sa[i], lcp[i], S.substr(sa[i]));
  }

  auto getLongestCommonStringFrom = [&](int a, int b) {
    int L = min(lcp.rank[a], lcp.rank[b]);
    int R = max(lcp.rank[a], lcp.rank[b]);
    return seg.query(L, R);
  };

  int Q;
  cin >> Q;
  for (int i = 0; i < Q; i++) {
    int l, r, t;
    cin >> l >> r >> t;
    if (t == r - l + 1) {
      cout << "Yes" << endl;
      continue;
    }

    l--;

    int common_len = getLongestCommonStringFrom(l, l + t);
    dmp(common_len);
    if (common_len >= r - l - t) {
      cout << "Yes" << endl;
      continue;
    }

    vector<int> fix_cand;
    fix_cand.push_back(l + common_len);
    fix_cand.push_back(l + t + common_len);
    dmp(fix_cand);

    bool found = false;
    for (int cand : fix_cand) {
      if (cand < l + t) {
        if (getLongestCommonStringFrom(cand + 1, cand + 1 + t) >=
            r - l - t - common_len - 1) {
          found = true;
          break;
        }
      }
      if (cand >= r - t) {
        if (getLongestCommonStringFrom(cand + 1, cand + 1 - t) >=
            r - l - t - common_len - 1) {
          found = true;
          break;
        }
      }
      if (l + t <= cand && cand < r - t) {
        if (S[cand - t] == S[cand + t]) {
          int common_len_middle =
              getLongestCommonStringFrom(cand - t + 1, cand + 1);
          if (common_len_middle >= t - 1) {
            if (getLongestCommonStringFrom(cand + 1, cand + 1 + t) >=
                r - l - t - common_len - 2 - common_len_middle) {
              found = true;
              break;
            }
          }
        }
      }
    }

    if (found)
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }
  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 6496
final_rank: 8

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
//const int mod = 1e9 + 7;
const int mod = 998244353;

// 最初にbaseをgenBase()でランダムに生成すること！！！！！！！！！
// RollingHash(s, base) := 文字列sのハッシュテーブルを計算する
// get(l, r) := [l, r)のハッシュ値を求める
// connect(h1, h2, h2len) := ハッシュ値h1と, 長さh2lenのハッシュ値h2を結合する。
// LCP(b, l1, r1, l2, r2) := 区間[l1, r1)と、ハッシュテーブルがbである区間[l2,
// r2)の文字列の 最長共通接頭辞の長さを求める。
struct RollingHash {
    using ull = unsigned long long;
    using ui128 = __uint128_t;
    static const ull mod = (1ULL << 61) - 1;
    const ull base;
    vector<ull> hashed, power;

    inline ull add(ull a, ull b) {
        if((a += b) >= mod) { a -= mod; }
        return a;
    }
    inline ull mul(ull a, ull b) {
        ui128 t = (ui128)a * b;
        ull na = t >> 61;
        ull nb = t & mod;
        if((na += nb) >= mod) { na -= mod; }
        return na;
    }
    static inline ull genBase() {
        random_device seed_gen;
        mt19937_64 engine(seed_gen());
        uniform_int_distribution<ull> rand(2, mod - 2);
        return rand(engine);
    }
    RollingHash() = default;
    RollingHash(const string &s, ull base) : base(base) {
        int n = (int)s.size();
        hashed.assign(n + 1, 0);
        power.assign(n + 1, 0);
        power[0] = 1;
        for(int i = 0; i < n; i++) {
            power[i + 1] = mul(power[i], base);
            hashed[i + 1] = add(mul(hashed[i], base), s[i]);
        }
    }
    ull get(int l, int r) {
        return add(hashed[r], mod - mul(hashed[l], power[r - l]));
    }
    ull connect(ull h1, ull h2, int h2len) {
        return add(mul(h1, power[h2len]), h2);
    }
    int LCP(RollingHash &b, int l1, int r1, int l2, int r2) {
        assert(mod == b.mod);
        int len = min(r1 - l1, r2 - l2);
        int low = -1, high = len + 1;
        while(high - low > 1) {
            int mid = (low + high) >> 1;
            if(get(l1, l1 + mid) == b.get(l2, l2 + mid)) {
                low = mid;
            } else {
                high = mid;
            }
        }
        return low;
    }
};

int main(){
	string s; cin >> s;
	auto base = RollingHash::genBase();
	RollingHash rh(s,base);
	int q; cin >> q;
	while(q--){
		int l,r,t; cin >> l >> r >> t; l--;
		if(r-l <= t){
			cout << "Yes\n";
			continue;
		}
		int lcp = rh.LCP(rh,l,r,l+t,r);
		if(r-l <= 2*t){
			if(lcp >= r-l-t-1 || rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == r-l-t-lcp-1) cout << "Yes\n";
			else cout << "No\n";
		}else{
			bool yes = false;
			if(lcp < t){
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == r-l-t-lcp-1) yes = true;
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == t-1){
					if(l+t*2+lcp >= r){
						yes = true;
					}else if(rh.LCP(rh,l+lcp+t+1,r,l+t*2+lcp+1,r) == r-l-t*2-lcp-1 && s[l+lcp] == s[l+t*2+lcp]){
						yes = true;
					}
				}
			}else{
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == min(t-1,r-l-t-lcp-1)){
					if(l+t*2+lcp+1 >= r){
						yes = true;
					}else if(rh.LCP(rh,l+lcp+t+1,r,l+t*2+lcp+1,r) == r-l-t*2-lcp-1 && s[l+lcp] == s[l+t*2+lcp]){
						yes = true;
					}
				}
			}
			if(yes) cout << "Yes\n";
			else cout << "No\n";
		}
	}
}
accuracy: 1
time_ms: 150
memory_kb: 4964
final_rank: 9

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
//const int mod = 1e9 + 7;
const int mod = 998244353;

// 最初にbaseをgenBase()でランダムに生成すること！！！！！！！！！
// RollingHash(s, base) := 文字列sのハッシュテーブルを計算する
// get(l, r) := [l, r)のハッシュ値を求める
// connect(h1, h2, h2len) := ハッシュ値h1と, 長さh2lenのハッシュ値h2を結合する。
// LCP(b, l1, r1, l2, r2) := 区間[l1, r1)と、ハッシュテーブルがbである区間[l2,
// r2)の文字列の 最長共通接頭辞の長さを求める。
struct RollingHash {
    using ull = unsigned long long;
    using ui128 = __uint128_t;
    static const ull mod = (1ULL << 61) - 1;
    const ull base;
    vector<ull> hashed, power;

    inline ull add(ull a, ull b) {
        if((a += b) >= mod) { a -= mod; }
        return a;
    }
    inline ull mul(ull a, ull b) {
        ui128 t = (ui128)a * b;
        ull na = t >> 61;
        ull nb = t & mod;
        if((na += nb) >= mod) { na -= mod; }
        return na;
    }
    static inline ull genBase() {
        random_device seed_gen;
        mt19937_64 engine(seed_gen());
        uniform_int_distribution<ull> rand(2, mod - 2);
        return rand(engine);
    }
    RollingHash() = default;
    RollingHash(const string &s, ull base) : base(base) {
        int n = (int)s.size();
        hashed.assign(n + 1, 0);
        power.assign(n + 1, 0);
        power[0] = 1;
        for(int i = 0; i < n; i++) {
            power[i + 1] = mul(power[i], base);
            hashed[i + 1] = add(mul(hashed[i], base), s[i]);
        }
    }
    ull get(int l, int r) {
        return add(hashed[r], mod - mul(hashed[l], power[r - l]));
    }
    ull connect(ull h1, ull h2, int h2len) {
        return add(mul(h1, power[h2len]), h2);
    }
    int LCP(RollingHash &b, int l1, int r1, int l2, int r2) {
        assert(mod == b.mod);
        int len = min(r1 - l1, r2 - l2);
        int low = -1, high = len + 1;
        while(high - low > 1) {
            int mid = (low + high) >> 1;
            if(get(l1, l1 + mid) == b.get(l2, l2 + mid)) {
                low = mid;
            } else {
                high = mid;
            }
        }
        return low;
    }
};

int main(){
	string s; cin >> s;
	auto base = RollingHash::genBase();
	RollingHash rh(s,base);
	int q; cin >> q;
	while(q--){
		int l,r,t; cin >> l >> r >> t; l--;
		if(r-l <= t){
			cout << "Yes\n";
			continue;
		}
		int lcp = rh.LCP(rh,l,r,l+t,r);
		if(r-l <= 2*t){
			if(lcp >= r-l-t-1 || rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == r-l-t-lcp-1) cout << "Yes\n";
			else cout << "No\n";
		}else{
			bool yes = false;
			if(lcp < t){
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == r-l-t-lcp-1) yes = true;
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == min(t-1,r-l-t-lcp-1) && 
					(l+t*2+lcp+1 >= r || rh.LCP(rh,l+lcp+t+1,r,l+t*2+lcp+1,r)) == r-l-t*2-lcp-1 && s[l+lcp] == s[l+t*2+lcp]){
					yes = true;
				}
			}else{
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == min(t-1,r-l-t-lcp-1) && 
					(l+t*2+lcp+1 >= r || rh.LCP(rh,l+lcp+t+1,r,l+t*2+lcp+1,r) == r-l-t*2-lcp-1 && s[l+lcp] == s[l+t*2+lcp])){
					yes = true;
				}
			}
			if(yes) cout << "Yes\n";
			else cout << "No\n";
		}
	}
}
accuracy: 0.05128205128205128
time_ms: 130
memory_kb: 4928
final_rank: 18

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
//const int mod = 1e9 + 7;
const int mod = 998244353;

// 最初にbaseをgenBase()でランダムに生成すること！！！！！！！！！
// RollingHash(s, base) := 文字列sのハッシュテーブルを計算する
// get(l, r) := [l, r)のハッシュ値を求める
// connect(h1, h2, h2len) := ハッシュ値h1と, 長さh2lenのハッシュ値h2を結合する。
// LCP(b, l1, r1, l2, r2) := 区間[l1, r1)と、ハッシュテーブルがbである区間[l2,
// r2)の文字列の 最長共通接頭辞の長さを求める。
struct RollingHash {
    using ull = unsigned long long;
    using ui128 = __uint128_t;
    static const ull mod = (1ULL << 61) - 1;
    const ull base;
    vector<ull> hashed, power;

    inline ull add(ull a, ull b) {
        if((a += b) >= mod) { a -= mod; }
        return a;
    }
    inline ull mul(ull a, ull b) {
        ui128 t = (ui128)a * b;
        ull na = t >> 61;
        ull nb = t & mod;
        if((na += nb) >= mod) { na -= mod; }
        return na;
    }
    static inline ull genBase() {
        random_device seed_gen;
        mt19937_64 engine(seed_gen());
        uniform_int_distribution<ull> rand(2, mod - 2);
        return rand(engine);
    }
    RollingHash() = default;
    RollingHash(const string &s, ull base) : base(base) {
        int n = (int)s.size();
        hashed.assign(n + 1, 0);
        power.assign(n + 1, 0);
        power[0] = 1;
        for(int i = 0; i < n; i++) {
            power[i + 1] = mul(power[i], base);
            hashed[i + 1] = add(mul(hashed[i], base), s[i]);
        }
    }
    ull get(int l, int r) {
        return add(hashed[r], mod - mul(hashed[l], power[r - l]));
    }
    ull connect(ull h1, ull h2, int h2len) {
        return add(mul(h1, power[h2len]), h2);
    }
    int LCP(RollingHash &b, int l1, int r1, int l2, int r2) {
        assert(mod == b.mod);
        int len = min(r1 - l1, r2 - l2);
        int low = -1, high = len + 1;
        while(high - low > 1) {
            int mid = (low + high) >> 1;
            if(get(l1, l1 + mid) == b.get(l2, l2 + mid)) {
                low = mid;
            } else {
                high = mid;
            }
        }
        return low;
    }
};

int main(){
	string s; cin >> s;
	auto base = RollingHash::genBase();
	RollingHash rh(s,base);
	int q; cin >> q;
	while(q--){
		int l,r,t; cin >> l >> r >> t; l--;
		if(r-l <= t){
			cout << "Yes\n";
			continue;
		}
		int lcp = rh.LCP(rh,l,r,l+t,r);
		if(r-l <= 2*t){
			if(lcp >= r-l-t-1 || rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r)) cout << "Yes\n";
			else cout << "No\n";
		}else{
			bool yes = false;
			if(lcp < t){
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == r-l-t-lcp-1) yes = true;
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == min(t-1,r-l-t-lcp-1) && 
					(l+t*2+lcp+1 >= r || rh.LCP(rh,l+lcp+t+1,r,l+t*2+lcp+1,r)) == r-l-t*2-lcp-1 && s[l+lcp] == s[l+t*2+lcp]){
					yes = true;
				}
			}else{
				if(rh.LCP(rh,l+lcp+1,r,l+t+lcp+1,r) == min(t-1,r-l-t-lcp-1) && 
					(l+t*2+lcp+1 >= r || rh.LCP(rh,l+lcp+t+1,r,l+t*2+lcp+1,r) == r-l-t*2-lcp-1 && s[l+lcp] == s[l+t*2+lcp])){
					yes = true;
				}
			}
			if(yes) cout << "Yes\n";
			else cout << "No\n";
		}
	}
}
accuracy: 0.05128205128205128
time_ms: 130
memory_kb: 4928
final_rank: 18

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

struct RollingHash {
  int Mod, Base;
  vector<int> pow;
  vector<vector<int>> hash;
  // mod : 1e9 + 9,base : 1007
  RollingHash(const int len = 3000000, const int mod = (int)(1e9 + 7),
              const int base = 1009) {
    Mod = mod;
    Base = base;
    pow.assign(len + 1, 0);
    pow[0] = 1;
    for (int i = 1; i <= len; ++i) pow[i] = 1LL * pow[i - 1] * Base % Mod;
  }
  template <class T>
  int add(const T &s) {
    int id = hash.size();
    hash.push_back(vector<int>());
    sethash(id, s);
    return id;
  }
  template <class T>
  void sethash(const int id, const T &s) {
    assert(id < (int)hash.size());
    int len = s.size();
    hash[id].resize(len + 1, 0);
    for (int i = 0; i < len; ++i) {
      hash[id][i + 1] = 1LL * hash[id][i] * Base % Mod;
      if ((hash[id][i + 1] += s[i] + 1) >= Mod) hash[id][i + 1] -= Mod;
    }
  }
  // [l,r),0-indexed
  inline int calchash(const int &id, const int &l, const int &r) const {
    assert(r >= l);
    int res = hash[id][r];
    res += Mod - 1LL * hash[id][l] * pow[r - l] % Mod;
    if (res >= Mod) res -= Mod;
    return res;
  }
  inline bool issame(const int &idl, const int &ll, const int &lr,
                     const int &idr, const int &rl, const int &rr) const {
    return calchash(idl, ll, lr) == calchash(idr, rl, rr);
  }
};

int n, q, l, r, t;
string s;
RollingHash rh;
vector<int> memo;

int solve(int sl, int sr);
void prepair(int hash);
int calc_hash(int len, int id, int sl, int st);

int main() {
  cin >> s >> q;
  n = s.size();
  rh.add(s);
  reverse(s.begin(), s.end());
  rh.add(s);
  while (q--) {
    cin >> l >> r >> t, --l;
    if (solve(l, l + t) || solve(r - t, r))
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }
  return 0;
}

int solve(int sl, int sr) {
  vector<int> memo(2), st(2);
  if (sl == l) {
    memo[0] = rh.calchash(0, sl, sr), st[0] = sl;
    swap(sl, sr);
    sl = n - sl, sr = n - sr;
    swap(l, r);
    l = n - l, r = n - r;
    int rem = t - (r - l) % t, now = rh.calchash(1, sl + rem, sr);
    now = 1LL * now * rh.pow[rem] % rh.Mod;
    (now += rh.calchash(1, sl, sl + rem)) %= rh.Mod;
    memo[1] = now, st[1] = sl + rem;
    swap(sl, sr);
    sl = n - sl, sr = n - sr;
    swap(l, r);
    l = n - l, r = n - r;
  } else {
    swap(sl, sr);
    sl = n - sl, sr = n - sr;
    swap(l, r);
    l = n - l, r = n - r;
    memo[1] = rh.calchash(1, sl, sr), st[1] = sl;
    swap(sl, sr);
    sl = n - sl, sr = n - sr;
    swap(l, r);
    l = n - l, r = n - r;
    int rem = t - (r - l) % t, now = rh.calchash(0, sl + rem, sr);
    now = 1LL * now * rh.pow[rem] % rh.Mod;
    (now += rh.calchash(0, sl, sl + rem)) %= rh.Mod;
    memo[0] = now, st[0] = sl + rem;
  }
  int res = 0;
  for (int times = 0; times < 2; ++times) {
    prepair(memo[times]);
    if (calc_hash(r - l, times, sl, st[times]) == rh.calchash(times, l, r))
      return 1;
    int lef = 0, righ = r - l;
    while (righ - lef > 1) {
      int mid = (lef + righ) >> 1;
      if (calc_hash(mid, times, sl, st[times]) ==
          rh.calchash(times, l, l + mid))
        lef = mid;
      else
        righ = mid;
    }
    res += righ;
    swap(sl, sr);
    sl = n - sl, sr = n - sr;
    swap(l, r);
    l = n - l, r = n - r;
  }
  return res == r - l + 1;
}

void prepair(int hash) {
  int len = t;
  memo.assign(1, hash);
  while (len < r - l) {
    int now = 1LL * memo.back() * rh.pow[len] % rh.Mod;
    (now += memo.back()) %= rh.Mod;
    memo.push_back(now);
    len <<= 1;
  }
}

int calc_hash(int len, int id, int sl, int st) {
  int cnt = len / t, m = memo.size(), res = 0;
  len %= t;
  for (int i = 0; i < m; ++i)
    if (cnt >> i & 1) {
      res = 1LL * res * rh.pow[t * (1 << i)] % rh.Mod;
      (res += memo[i]) %= rh.Mod;
    }
  int now = min(sl + t - st, len);
  res = 1LL * res * rh.pow[now] % rh.Mod;
  (res += rh.calchash(id, st, st + now)) %= rh.Mod;
  len -= now;
  res = 1LL * res * rh.pow[len] % rh.Mod;
  (res += rh.calchash(id, sl, sl + len)) %= rh.Mod;
  return res;
}
accuracy: 1
time_ms: 720
memory_kb: 15944
final_rank: 10

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

struct RollingHash {
  int Mod, Base;
  vector<int> pow;
  vector<vector<int>> hash;
  // mod : 1e9 + 9,base : 1007
  RollingHash(const int len = 3000000, const int mod = (int)(1e9 + 7),
              const int base = 1009) {
    Mod = mod;
    Base = base;
    pow.assign(len + 1, 0);
    pow[0] = 1;
    for (int i = 1; i <= len; ++i) pow[i] = 1LL * pow[i - 1] * Base % Mod;
  }
  template <class T>
  int add(const T &s) {
    int id = hash.size();
    hash.push_back(vector<int>());
    sethash(id, s);
    return id;
  }
  template <class T>
  void sethash(const int id, const T &s) {
    assert(id < (int)hash.size());
    int len = s.size();
    hash[id].resize(len + 1, 0);
    for (int i = 0; i < len; ++i) {
      hash[id][i + 1] = 1LL * hash[id][i] * Base % Mod;
      if ((hash[id][i + 1] += s[i] + 1) >= Mod) hash[id][i + 1] -= Mod;
    }
  }
  // [l,r),0-indexed
  inline int calchash(const int &id, const int &l, const int &r) const {
    assert(r >= l);
    int res = hash[id][r];
    res += Mod - 1LL * hash[id][l] * pow[r - l] % Mod;
    if (res >= Mod) res -= Mod;
    return res;
  }
  inline bool issame(const int &idl, const int &ll, const int &lr,
                     const int &idr, const int &rl, const int &rr) const {
    return calchash(idl, ll, lr) == calchash(idr, rl, rr);
  }
};

int n, q, l, r, t;
string s;
RollingHash rh;
vector<int> memo;

int solve(int sl, int sr);
void prepair(int hash);
int calc_hash(int len, int id, int st);

int main() {
  cin >> s >> q;
  n = s.size();
  rh.add(s);
  reverse(s.begin(), s.end());
  rh.add(s);
  while (q--) {
    cin >> l >> r >> t, --l;
    if (solve(l, l + t) || solve(r - t, r))
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }
  return 0;
}

int solve(int sl, int sr) {
  int res = 0;
  for (int times = 0; times < 2; ++times) {
    prepair(rh.calchash(times, sl, sr));
    if (calc_hash(r - l, times, sl) == rh.calchash(times, l, r)) return 1;
    int lef = 0, righ = r - l;
    while (righ - lef > 1) {
      int mid = (lef + righ) >> 1;
      if (calc_hash(mid, times, sl) == rh.calchash(times, l, l + mid))
        lef = mid;
      else
        righ = mid;
    }
    res += righ;
    swap(sl, sr);
    sl = n - sl, sr = n - sr;
    swap(l, r);
    l = n - l, r = n - r;
  }
  return res == r - l + 1;
}

void prepair(int hash) {
  int len = t;
  memo.assign(1, hash);
  while (len < r - l) {
    int now = 1LL * memo.back() * rh.pow[len] % rh.Mod;
    (now += memo.back()) %= rh.Mod;
    memo.push_back(now);
    len <<= 1;
  }
}

int calc_hash(int len, int id, int st) {
  int cnt = len / t, m = memo.size(), res = 0;
  len %= t;
  for (int i = 0; i < m; ++i)
    if (cnt >> i & 1) {
      res = 1LL * res * rh.pow[t * (1 << i)] % rh.Mod;
      (res += memo[i]) %= rh.Mod;
    }
  res = 1LL * res * rh.pow[len] % rh.Mod;
  (res += rh.calchash(id, st, st + len)) %= rh.Mod;
  return res;
}
accuracy: 0.05128205128205128
time_ms: 330
memory_kb: 15972
final_rank: 20

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

template <typename T> class seg_tree{
    //monoid
private:
    function<T(T,T)> func;
    T e;
    int N,n=-1;
    vector<T> seg;

    void init(){
        assert(n>=0);
        int i;
        for(i=0;(1<<i)<n;i++);
        N=(1<<i)-1;
        seg.assign(2*(N+1),e);
    }

    void init_reload(){
        for(int i=N-1;i>=0;i--){
            seg[i]=func(seg[2*i+1],seg[2*i+2]);
        }
    }
    
    void update(int pos){
        T a=func(seg[pos*2+1],seg[pos*2+2]);
        if(seg[pos]==a)return;
        seg[pos]=a;
        if(pos==0)return;
        update((pos-1)/2);
    }

public:
    seg_tree(function<T(T,T)> _func,T _e,int _n):func(_func),e(_e),n(_n){
        init();
    }
    seg_tree(function<T(T,T)> _func,T _e,vector<T> vec):func(_func),e(_e){
        n=vec.size();
        init();
        for(int i=0;i<n;i++){
            seg[N+i]=vec[i];
        }
        init_reload();
    }
    seg_tree(function<T(T,T)> _func,T _e,int _n,T a):func(_func),e(_e),n(_n){
        init(e);
        for(int i=0;i<n;i++){
            seg[N+i]=a;
        }
        init_reload();
    }

    int size()const{
        return n;
    }

    void set(int pos,T a){
        assert(pos>=0 && pos<=N);
        pos+=N;
        seg[pos]=a;
        update((pos-1)/2);
    }

    T get(const int pos)const{
        return seg[N+pos];
    }

    T search(int a,int b,int l,int r,int x){//[a,b) search
        if(a<=l && r<=b)return seg[x];
        int m=(l+r)/2;
        if(b<=m)return search(a,b,l,m,2*x+1);
        if(m<=a)return search(a,b,m,r,2*x+2);
        return func(search(a,m,l,m,2*x+1),search(m,b,m,r,2*x+2));
    }
    T search(int a,int b){
        assert(a<b);
        assert(0<=a && b<=size());
        return search(a,b,0,N+1,0);
    }
    T search(){
        return search(0,size());
    }

    int max_right(function<bool(T)>& g,int pos,int l,int r,int x,T& y){
        //suppose that S is return value, g(func(pos,..,S-1))=true,g(func(pos,..,S))=false
        if(pos<=l && g(func(y,seg[x]))){
            y=func(y,seg[x]);
            return r;
        }
        if(l+1==r)return l;
        int m=(l+r)/2;
        if(pos<m){
            int s=max_right(g,pos,l,m,2*x+1,y);
            if(s<m)return s;
        }
        return max_right(g,pos,m,r,2*x+2,y);
    }
    int max_right(function<bool(T)> g,int pos){
        T y=e;
        int s=max_right(g,pos,0,N+1,0,y);
        return min(s,n);
    }

    int min_left(function<bool(T)>& g,int pos,int l,int r,int x,T& y){
        //suppose that S is return value, g(func(S,..,pos-1))=true,g(func(S-1,..,pos-1))=false
        int s;
        if(r<=pos && g(func(seg[x],y))){
            y=func(seg[x],y);
            return l;
        }
        if(l+1==r)return r;
        int m=(l+r)/2;
        if(m<pos){
            s=min_left(g,pos,m,r,2*x+2,y);
            if(m<s)return s;
        }
        return min_left(g,pos,l,m,2*x+1,y);
    }
    int min_left(function<bool(T)> g,int pos){
        assert(pos>=0);
        if(pos==0)return 0;
        T y=e;
        return min_left(g,pos,0,N+1,0,y);
    }
};

namespace sol{
    const LL A=29,N=1e9+7,AN=1e5+7;
    LL Apow[AN];

    void solve(){
        int n,m;
        int i,j,k;
        LL a,b,c;
        LL s1,s2;
        string sa;
        Apow[0]=1;
        for(i=1;i<AN;i++){
            Apow[i]=Apow[i-1]*A%N;
        }
        cin>>sa;
        n=sa.size();
        cin>>m;
        seg_tree<LP> seg([&](LP a,LP b)->LP{
            LL c=a.first*Apow[b.second]+b.first;
            return {c%N,a.second+b.second};
        },{0,0},n);
        for(i=0;i<n;i++){
            a=sa[i]-'a';
            seg.set(i,{a,1});
        }
        for(i=0;i<m;i++){
            cin>>a>>b>>c;
            a--;
            LL z[3]={0,b-a-c+1};
            while(z[1]-z[0]>1){
                z[2]=(z[0]+z[1])/2;
                if(seg.search(a,a+z[2])==seg.search(a+c,a+c+z[2]))z[0]=z[2];
                else z[1]=z[2];
            }
            s1=z[0];
            z[0]=0,z[1]=b-a-c+1;
            while(z[1]-z[0]>1){
                z[2]=(z[0]+z[1])/2;
                if(seg.search(b-z[2],b)==seg.search(b-c-z[2],b-c))z[0]=z[2];
                else z[1]=z[2];
            }
            s2=z[0];
            if(b-a-c-1<=s1+s2){
                cout<<"Yes"<<endl;
                continue;
            }
            seg.set(a+s1+c,{sa[a+s1]-'a',1});
            if(seg.search(a,b-c)==seg.search(a+c,b))cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
            seg.set(a+s1+c,{sa[a+s1+c]-'a',1});
        }
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 1
time_ms: 950
memory_kb: 8308
final_rank: 11

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

struct RollingHash {
private:
    using i128 = __int128_t;
    using ull = unsigned long long;
    string str;
    vector<ull> hashed, power;
    const ull mod = (1uL << 61) - 1;
    const ull base = 1e9 + 7;
    const ull mask30 = (1ul << 30) - 1;
    const ull mask31 = (1ul << 31) - 1;
    ull mul(i128 a, i128 b) const {
        i128 t = a * b;
        t = (t >> 61) + (t & mod);
        if (t >= mod)
            return (ull)(t - mod);
        return (ull)t;
    }

public:
    void set(const string& _str) {
        str = _str;
        hashed.resize(str.size() + 1, 0);
        power.resize(str.size() + 1, 1);
        for (int i = 0; i < (int)str.size(); i++) {
            hashed[i + 1] = mul(hashed[i], base) + str[i] + 1;
            power[i + 1] = mul(power[i], base);
            if (hashed[i + 1] >= mod)
                hashed[i + 1] -= mod;
        }
    }
    RollingHash() : str(){};
    RollingHash(const string& str) : str() {
        set(str);
    };
    ull hash() const { return hashed.back(); }
    ull hash(int l, int r) const {
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        return ret < mod ? ret : ret - mod;
    }
    ull hashchg(int l, int r, int pos, char c) const {
        if (pos < l || r <= pos)
            return hash(l, r);
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        ret = ret < mod ? ret : ret - mod;
        ret += mod + mul(power[r - pos - 1], c) - mul(power[r - pos - 1], str[pos]);
        for (int i = 0; i < 2; i++) {
            ret = ret < mod ? ret : ret - mod;
        }
        return ret;
    }
    int size() const { return (int)str.size(); }
};


int main() {
    string S;
    int Q;
    cin >> S >> Q;
    RollingHash hash(S);

    while (Q--) {
        int l, r, t;
        cin >> l >> r >> t;
        l--;
        int l1 = l, l2 = l + t;
        int r1 = r - t, r2 = r;
        int ok = 0;
        int ng = r - l + 1 - t;
        while (abs(ok - ng) > 1) {
            int mid = (ok + ng) / 2;
            if (hash.hash(l1, l1 + mid) == hash.hash(l2, l2 + mid)) {
                ok = mid;
            } else {
                ng = mid;
            }
        }
        int pos1 = l1 + ok, pos2 = l2 + ok;
        bool ans;
        if (pos2 == r) {
            ans = true;
        } else {
            char c1 = S[pos1], c2 = S[pos2];
            if (hash.hashchg(l1, r1, pos1, c2) == hash.hashchg(l2, r2, pos1, c2) || hash.hashchg(l1, r1, pos2, c1) == hash.hashchg(l2, r2, pos2, c1))
                ans = true;
            else
                ans = false;
        }
        cout << (ans ? "Yes" : "No") << endl;
    }
}
accuracy: 1
time_ms: 140
memory_kb: 4924
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;

struct RollingHash {
private:
    using i128 = __int128_t;
    string str;
    vector<ull> hashed, power;
    const ull mod = (1uL << 61) - 1;
    const ull base = 1e9 + 7;
    const ull mask30 = (1ul << 30) - 1;
    const ull mask31 = (1ul << 31) - 1;
    ull mul(i128 a, i128 b) const {
        i128 t = a * b;
        t = (t >> 61) + (t & mod);
        if (t >= mod)
            return (ull)(t - mod);
        return (ull)t;
    }

public:
    void set(const string& _str) {
        str = _str;
        hashed.resize(str.size() + 1, 0);
        power.resize(str.size() + 1, 1);
        for (int i = 0; i < str.size(); i++) {
            hashed[i + 1] = mul(hashed[i], base) + str[i] + 1;
            power[i + 1] = mul(power[i], base);
            if (hashed[i + 1] >= mod)
                hashed[i + 1] -= mod;
        }
    }
    RollingHash() : str(){};
    RollingHash(const string& str) : str() {
        set(str);
    };
    ull hash() const { return hashed.back(); }
    ull hash(int l, int r) const {
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        return ret < mod ? ret : ret - mod;
    }
    ull hash(int l, int r, int pos, char c) const {
        if (pos < l || r <= pos)
            return hash(l, r);
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        /* ret = ret < mod ? ret : ret - mod; */
        ret += mod + mul(power[r - pos - 1], c) - mul(power[r - pos - 1], str[pos]);
        for (int i = 0; i < 3; i++) {
            ret = ret < mod ? ret : ret - mod;
        }
        return ret;
    }
    int size() const { return str.size(); }
};


int main() {
    string S;
    int Q;
    cin >> S >> Q;
    RollingHash hash(S);

    while (Q--) {
        int l, r, t;
        cin >> l >> r >> t;
        l--;
        int l1 = l, l2 = l + t;
        int r1 = r - t, r2 = r;
        int ok = 0;
        int ng = r - l + 1 - t;
        while (abs(ok - ng) > 1) {
            int mid = (ok + ng) / 2;
            if (hash.hash(l1, l1 + mid) == hash.hash(l2, l2 + mid)) {
                ok = mid;
            } else {
                ng = mid;
            }
        }
        int pos1 = l1 + ok, pos2 = l2 + ok;
        bool ans;
        if (pos2 == r) {
            ans = true;
        } else {
            char c1 = S[pos1], c2 = S[pos2];
            if (hash.hash(l1, r1, pos1, c2) == hash.hash(l2, r2, pos1, c2) || hash.hash(l1, r1, pos2, c1) == hash.hash(l2, r2, pos2, c1))
                ans = true;
            else
                ans = false;
        }
        cout << (ans ? "Yes" : "No") << endl;
    }
}
accuracy: 1
time_ms: 140
memory_kb: 4956
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;

struct RollingHash {
private:
    using i128 = __int128_t;
    string str;
    vector<ull> hashed, power;
    const ull mod = (1uL << 61) - 1;
    const ull base = 1e9 + 7;
    const ull mask30 = (1ul << 30) - 1;
    const ull mask31 = (1ul << 31) - 1;
    ull mul(i128 a, i128 b) const {
        i128 t = a * b;
        t = (t >> 61) + (t & mod);
        if (t >= mod)
            return (ull)(t - mod);
        return (ull)t;
    }

public:
    void set(const string& _str) {
        str = _str;
        hashed.resize(str.size() + 1, 0);
        power.resize(str.size() + 1, 1);
        for (int i = 0; i < str.size(); i++) {
            hashed[i + 1] = mul(hashed[i], base) + str[i] + 1;
            power[i + 1] = mul(power[i], base);
            if (hashed[i + 1] >= mod)
                hashed[i + 1] -= mod;
        }
    }
    RollingHash() : str(){};
    RollingHash(const string& str) : str() {
        set(str);
    };
    ull hash() const { return hashed.back(); }
    ull hash(int l, int r) const {
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        return ret < mod ? ret : ret - mod;
    }
    ull hash(int l, int r, int pos, char c) const {
        if (pos < l || r <= pos)
            return hash(l, r);
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        ret = ret < mod ? ret : ret - mod;
        ret += mod + mul(power[r - pos - 1], c) - mul(power[r - pos - 1], str[pos]);
        for (int i = 0; i < 2; i++) {
            ret = ret < mod ? ret : ret - mod;
        }
        return ret;
    }
    int size() const { return str.size(); }
};


int main() {
    string S;
    int Q;
    cin >> S >> Q;
    RollingHash hash(S);

    while (Q--) {
        int l, r, t;
        cin >> l >> r >> t;
        l--;
        int l1 = l, l2 = l + t;
        int r1 = r - t, r2 = r;
        int ok = 0;
        int ng = r - l + 1 - t;
        while (abs(ok - ng) > 1) {
            int mid = (ok + ng) / 2;
            if (hash.hash(l1, l1 + mid) == hash.hash(l2, l2 + mid)) {
                ok = mid;
            } else {
                ng = mid;
            }
        }
        int pos1 = l1 + ok, pos2 = l2 + ok;
        bool ans;
        if (pos2 == r) {
            ans = true;
        } else {
            char c1 = S[pos1], c2 = S[pos2];
            if (hash.hash(l1, r1, pos1, c2) == hash.hash(l2, r2, pos1, c2) || hash.hash(l1, r1, pos2, c1) == hash.hash(l2, r2, pos2, c1))
                ans = true;
            else
                ans = false;
        }
        cout << (ans ? "Yes" : "No") << endl;
    }
}
accuracy: 1
time_ms: 140
memory_kb: 4948
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;

struct RollingHash {
private:
    using i128 = __int128_t;
    string str;
    vector<ull> hashed, power;
    const ull mod = (1uL << 61) - 1;
    const ull base = 1e9 + 9;
    const ull mask30 = (1ul << 30) - 1;
    const ull mask31 = (1ul << 31) - 1;
    ull mul(i128 a, i128 b) const {
        i128 t = a * b;
        t = (t >> 61) + (t & mod);
        if (t >= mod)
            return (ull)(t - mod);
        return (ull)t;
    }

public:
    void set(const string& _str) {
        str = _str;
        hashed.resize(str.size() + 1, 0);
        power.resize(str.size() + 1, 1);
        for (int i = 0; i < str.size(); i++) {
            hashed[i + 1] = mul(hashed[i], base) + str[i] + 1;
            power[i + 1] = mul(power[i], base);
            if (hashed[i + 1] >= mod)
                hashed[i + 1] -= mod;
        }
    }
    RollingHash() : str(){};
    RollingHash(const string& str) : str() {
        set(str);
    };
    ull hash() const { return hashed.back(); }
    ull hash(int l, int r) const {
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        return ret < mod ? ret : ret - mod;
    }
    ull hash(int l, int r, int pos, char c) const {
        if (pos < l || r <= pos)
            return hash(l, r);
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        ret = ret < mod ? ret : ret - mod;
        ret += mod + mul(power[r - pos - 1], c) - mul(power[r - pos - 1], str[pos]);
        for (int i = 0; i < 2; i++) {
            ret = ret < mod ? ret : ret - mod;
        }
        return ret;
    }
    int size() const { return str.size(); }
};


int main() {
    string S;
    int Q;
    cin >> S >> Q;
    RollingHash hash(S);

    while (Q--) {
        int l, r, t;
        cin >> l >> r >> t;
        l--;
        int l1 = l, l2 = l + t;
        int r1 = r - t, r2 = r;
        int ok = 0;
        int ng = r - l + 1 - t;
        while (abs(ok - ng) > 1) {
            int mid = (ok + ng) / 2;
            if (hash.hash(l1, l1 + mid) == hash.hash(l2, l2 + mid)) {
                ok = mid;
            } else {
                ng = mid;
            }
        }
        int pos1 = l1 + ok, pos2 = l2 + ok;
        bool ans;
        if (pos2 == r) {
            ans = true;
        } else {
            char c1 = S[pos1], c2 = S[pos2];
            if (hash.hash(l1, r1, pos1, c2) == hash.hash(l2, r2, pos1, c2) || hash.hash(l1, r1, pos2, c1) == hash.hash(l2, r2, pos2, c1))
                ans = true;
            else
                ans = false;
        }
        cout << (ans ? "Yes" : "No") << endl;
    }
}
accuracy: 1
time_ms: 140
memory_kb: 4952
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;

struct RollingHash {
private:
    using i128 = __int128_t;
    string str;
    vector<ull> hashed, power;
    const ull mod = (1uL << 61) - 1;
    const ull base = 1e9 + 7;
    const ull mask30 = (1ul << 30) - 1;
    const ull mask31 = (1ul << 31) - 1;
    ull mul(i128 a, i128 b) const {
        i128 t = a * b;
        t = (t >> 61) + (t & mod);
        if (t >= mod)
            return (ull)(t - mod);
        return (ull)t;
    }

public:
    void set(const string& _str) {
        str = _str;
        hashed.resize(str.size() + 1, 0);
        power.resize(str.size() + 1, 1);
        for (int i = 0; i < str.size(); i++) {
            hashed[i + 1] = mul(hashed[i], base) + str[i] + 1;
            power[i + 1] = mul(power[i], base);
            if (hashed[i + 1] >= mod)
                hashed[i + 1] -= mod;
        }
    }
    RollingHash() : str(){};
    RollingHash(const string& str) : str() {
        set(str);
    };
    ull hash() const { return hashed.back(); }
    ull hash(int l, int r) const {
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        return ret < mod ? ret : ret - mod;
    }
    ull hash(int l, int r, int pos, char c) const {
        if (pos < l || r <= pos)
            return hash(l, r);
        ull ret = mod + hashed[r] - mul(hashed[l], power[r - l]);
        ret += mod + mul(power[r - pos - 1], c) - mul(power[r - pos - 1], str[pos]);
        for (int i = 0; i < 2; i++) {
            ret = ret < mod ? ret : ret - mod;
        }
        return ret;
    }
    int size() const { return str.size(); }
};


int main() {
    string S;
    int Q;
    cin >> S >> Q;
    RollingHash hash(S);

    while (Q--) {
        int l, r, t;
        cin >> l >> r >> t;
        l--;
        int l1 = l, l2 = l + t;
        int r1 = r - t, r2 = r;
        int ok = 0;
        int ng = r - l + 1 - t;
        while (abs(ok - ng) > 1) {
            int mid = (ok + ng) / 2;
            if (hash.hash(l1, l1 + mid) == hash.hash(l2, l2 + mid)) {
                ok = mid;
            } else {
                ng = mid;
            }
        }
        int pos1 = l1 + ok, pos2 = l2 + ok;
        bool ans;
        if (pos2 == r) {
            ans = true;
        } else {
            char c1 = S[pos1], c2 = S[pos2];
            if (hash.hash(l1, r1, pos1, c2) == hash.hash(l2, r2, pos1, c2) || hash.hash(l1, r1, pos2, c1) == hash.hash(l2, r2, pos2, c1))
                ans = true;
            else
                ans = false;
        }
        cout << (ans ? "Yes" : "No") << endl;
    }
}
accuracy: 0.05128205128205128
time_ms: 130
memory_kb: 4776
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=100005,INF=1<<29;
const int mod1=1000000007,mod2=1000000009;
const int M=400;

struct Rollinghash{
    string S;
    int n;
    int base1;
    int base2;
    vector<ll> h1,h2,ru1,ru2;
    
    void make(string &T,int ba1,int ba2){
        S=T;
        n=S.size();
        h1.assign(n+1,0);
        h2.assign(n+1,0);
        ru1.assign(n+1,0);
        ru2.assign(n+1,0);
        base1=ba1;
        base2=ba2;
        
        ru1[0]=1;
        ru2[0]=1;
        
        for(int i=1;i<=n;i++){
            h1[i]=h1[i-1]*base1+ll(S[i-1]-'A');
            h1[i]%=mod1;
            
            h2[i]=h2[i-1]*base2+ll(S[i-1]-'A');
            h2[i]%=mod2;
            
            ru1[i]=ru1[i-1]*base1%mod1;
            ru2[i]=ru2[i-1]*base2%mod2;
        }
    }
    
    pair<ll,ll> ha(int l,int r){
        pair<ll,ll> res;
        res.fi=(h1[r]-h1[l]*ru1[r-l]%mod1+mod1)%mod1;
        res.se=(h2[r]-h2[l]*ru2[r-l]%mod2+mod2)%mod2;
        
        return res;
    }//開区間
};

vector<int> ng[M+1];

Rollinghash ro;

int cnt(int l,int r,int len){
    if(ro.ha(l,l+len)==ro.ha(r,r+len)) return 0;
    int left=0,right=len;
    while(right-left>1){
        int mid=(left+right)/2;
        auto al=ro.ha(l+left,l+mid),ar=ro.ha(l+mid,l+right);
        auto bl=ro.ha(r+left,r+mid),br=ro.ha(r+mid,r+right);
        if(al!=bl&&ar!=br) return 2;
        if(al!=bl) right=mid;
        else left=mid;
    }
    return 1;
}

int solve(int l,int r,int t,int len){
    map<pair<ll,ll>,int> MA;
    for(int i=l;i<r;i+=t) MA[ro.ha(i,i+len)]++;
    if(si(MA)>=3) return 2;
    else if(si(MA)==1) return 0;
    else{
        int cc=0;
        for(auto a:MA) if(a.se>=2) cc++;
        if(cc==2) return 2;
        else{
            auto a=(*MA.begin()).fi;
            int sl=-1,sr=-1;
            for(int i=l;i<r;i+=t){
                if(ro.ha(i,i+len)==a) sl=i;
                else sr=i;
            }
            return cnt(sl,sr,len);
        }
    }
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    string S;cin>>S;
    int Q;cin>>Q;
    ro.make(S,137,199);
    int N=si(S);
    for(int t=1;t<=M;t++){
        for(int i=0;i+t<N;i++){
            if(S[i]!=S[i+t]) ng[t].push_back(i);
        }
    }
    
    while(Q--){
        int l,r,t;cin>>l>>r>>t;
        l--;
        if(t<=M){
            auto a=lower_bound(all(ng[t]),l),b=lower_bound(all(ng[t]),r-t);
            if(a==b) cout<<"Yes\n";
            else{
                if(b-a>=3) cout<<"No\n";
                else if(b-a==2){
                    int x=*a;
                    a++;
                    int y=*a;
                    if(y-x==t&&S[x]==S[y+t]) cout<<"Yes\n";
                    else cout<<"No\n";
                }else{
                    int x=*a;
                    if(x<l+t||x+t>=r-t) cout<<"Yes\n";
                    else cout<<"No\n";
                }
            }
        }else{
            if(r-l==t){
                cout<<"Yes\n";
            }else if(r-l<=2*t){
                int len=r-l-t;
                int x=cnt(l,l+t,len);
                if(x<=1) cout<<"Yes\n";
                else cout<<"No\n";
            }else{
                if(solve(l,r,t,(r-l)%t)+solve(l+(r-l)%t,r,t,t-(r-l)%t)<=1) cout<<"Yes\n";
                else cout<<"No\n";
            }
        }
    }
}
accuracy: 1
time_ms: 190
memory_kb: 153524
final_rank: 12

code_snippet: /*	author:  Kite_kuma
	created: 2021.08.16 12:53:59 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

class RollingHash_Mersenne {
	// safety rollinghash (mod : 1UL << 61 - 1, base : 10007 or random)
	// https://atcoder.jp/contests/agc047/submissions/16500504
	const unsigned long long MASK30 = (1ULL << 30) - 1;
	const unsigned long long MASK31 = (1ULL << 31) - 1;
	const unsigned long long MASK61 = (1ULL << 61) - 1;
	const unsigned long long MOD = MASK61;
	const unsigned long long base = 10007;	// 値が小さすぎると衝突しやすい
	const unsigned long long POSITIVIZER = MOD << 2;
	vector<unsigned long long> hash, power;

	// a * b と mod が等しい数を返す
	// 結果は (1UL << 63) + 3 - (1UL << 31) * 3 以下
	unsigned long long Mul(unsigned long long a, unsigned long long b) const {
		unsigned long long au = a >> 31;
		unsigned long long ad = a & MASK31;
		unsigned long long bu = b >> 31;
		unsigned long long bd = b & MASK31;
		unsigned long long mid = ad * bu + au * bd;
		unsigned long long midu = mid >> 30;
		unsigned long long midd = mid & MASK30;
		return au * bu * 2 + midu + (midd << 31) + ad * bd;
	}

	// mod 2^61-1を計算する
	unsigned long long CalcMod(unsigned long long x) const {
		unsigned long long xu = x >> 61;
		unsigned long long xd = x & MASK61;
		unsigned long long res = xu + xd;
		if(res >= MOD) res -= MOD;
		return res;
	}

   public:
	RollingHash_Mersenne() = default;
	RollingHash_Mersenne(const string &s, unsigned long long _base = 10007) : base(_base) {
		int sz = (int)s.size();
		hash.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for(int i = 0; i < sz; i++) {
			power[i + 1] = CalcMod(Mul(power[i], base));
			hash[i + 1] = CalcMod(Mul(hash[i], base) + s[i]);
		}
	}

	template <class T>
	RollingHash_Mersenne(const vector<T> &v, unsigned long long _base = 10007) : base(_base) {
		int sz = (int)v.size();
		hash.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for(int i = 0; i < sz; i++) {
			power[i + 1] = CalcMod(Mul(power[i], base));
			hash[i + 1] = CalcMod(Mul(hash[i], base) + v[i]);
		}
	}

	unsigned long long get(int l, int r) const { return CalcMod(hash[r] + POSITIVIZER - Mul(hash[l], power[r - l])); }

	unsigned long long connect(unsigned long long h1, unsigned long long h2, unsigned long long h2len) const {
		return CalcMod(Mul(h1, power[h2len]) + h2);
	}

	// Longest Common Prefix (using Binary Search)
	int LCP(int l_this, int r_this, RollingHash_Mersenne &other, int l_other, int r_other) {
		int len = min(r_this - l_this, r_other - l_other);
		int low = 0, high = len + 1;
		while(high - low > 1) {
			int mid = (low + high) / 2;
			if(get(l_this, l_this + mid) == other.get(l_other, l_other + mid))
				low = mid;
			else
				high = mid;
		}
		return low;
	}
};

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	STR(s);
	RollingHash_Mersenne rh(s);

	auto judge = [&](int l, int r, int t) {
		if(t >= r - l) return true;
		int lcp = rh.LCP(l, r, rh, l + t, r);
		if(lcp >= r - l - t - 1) return true;

		int diff = l + lcp;
		int e = diff + t;
		int f = diff + t + t;

		assert(s[diff] != s[e]);

		if(f < r) {
			if(s[diff] == s[f]) {
				if(rh.LCP(diff + 1, e, rh, e + 1, f) < f - e - 1) return false;
				if(rh.LCP(e + 1, r, rh, f + 1, r) < r - f - 1) return false;
				return true;
			} else if(s[e] == s[f]) {
				if(diff >= t + l) return false;
				if(rh.LCP(diff + 1, r, rh, e + 1, r) < r - e - 1) return false;
				return true;
			} else {
				return false;
			}
		}

		if(rh.LCP(l + lcp + 1, r, rh, l + t + lcp + 1, r) == r - lcp - 1 - t - l) return true;
		return false;
	};

	int q;
	cin >> q;
	rep(q) {
		int l, r;
		int t;
		cin >> l >> r >> t;
		l--;
		Yes(judge(l, r, t));
	}

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4860
final_rank: 1

code_snippet: /*	author:  Kite_kuma
	created: 2021.08.16 12:53:59 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

class RollingHash_Mersenne {
	// safety rollinghash (mod : 1UL << 61 - 1, base : 10007 or random)
	// https://atcoder.jp/contests/agc047/submissions/16500504
	const unsigned long long MASK30 = (1ULL << 30) - 1;
	const unsigned long long MASK31 = (1ULL << 31) - 1;
	const unsigned long long MASK61 = (1ULL << 61) - 1;
	const unsigned long long MOD = MASK61;
	const unsigned long long base = 10007;	// 値が小さすぎると衝突しやすい
	const unsigned long long POSITIVIZER = MOD << 2;
	vector<unsigned long long> hash, power;

	// a * b と mod が等しい数を返す
	// 結果は (1UL << 63) + 3 - (1UL << 31) * 3 以下
	unsigned long long Mul(unsigned long long a, unsigned long long b) const {
		unsigned long long au = a >> 31;
		unsigned long long ad = a & MASK31;
		unsigned long long bu = b >> 31;
		unsigned long long bd = b & MASK31;
		unsigned long long mid = ad * bu + au * bd;
		unsigned long long midu = mid >> 30;
		unsigned long long midd = mid & MASK30;
		return au * bu * 2 + midu + (midd << 31) + ad * bd;
	}

	// mod 2^61-1を計算する
	unsigned long long CalcMod(unsigned long long x) const {
		unsigned long long xu = x >> 61;
		unsigned long long xd = x & MASK61;
		unsigned long long res = xu + xd;
		if(res >= MOD) res -= MOD;
		return res;
	}

   public:
	RollingHash_Mersenne() = default;
	RollingHash_Mersenne(const string &s, unsigned long long _base = 10007) : base(_base) {
		int sz = (int)s.size();
		hash.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for(int i = 0; i < sz; i++) {
			power[i + 1] = CalcMod(Mul(power[i], base));
			hash[i + 1] = CalcMod(Mul(hash[i], base) + s[i]);
		}
	}

	template <class T>
	RollingHash_Mersenne(const vector<T> &v, unsigned long long _base = 10007) : base(_base) {
		int sz = (int)v.size();
		hash.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for(int i = 0; i < sz; i++) {
			power[i + 1] = CalcMod(Mul(power[i], base));
			hash[i + 1] = CalcMod(Mul(hash[i], base) + v[i]);
		}
	}

	unsigned long long get(int l, int r) const { return CalcMod(hash[r] + POSITIVIZER - Mul(hash[l], power[r - l])); }

	unsigned long long connect(unsigned long long h1, unsigned long long h2, unsigned long long h2len) const {
		return CalcMod(Mul(h1, power[h2len]) + h2);
	}

	// Longest Common Prefix (using Binary Search)
	int LCP(int l_this, int r_this, RollingHash_Mersenne &other, int l_other, int r_other) {
		int len = min(r_this - l_this, r_other - l_other);
		int low = 0, high = len + 1;
		while(high - low > 1) {
			int mid = (low + high) / 2;
			if(get(l_this, l_this + mid) == other.get(l_other, l_other + mid))
				low = mid;
			else
				high = mid;
		}
		return low;
	}
};

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	STR(s);
	RollingHash_Mersenne rh(s);

	auto judge = [&](int l, int r, int t) {
		if(t >= r - l) return true;
		int lcp = rh.LCP(l, r, rh, l + t, r);
		if(lcp >= r - l - t - 1) return true;

		int diff = l + lcp;
		int e = diff + t;
		int f = diff + t + t;

		assert(s[diff] != s[e]);

		if(f < r) {
			if(s[diff] == s[f]) {
				if(rh.LCP(diff + 1, e, rh, e + 1, f) < f - e - 1) return false;
				if(rh.LCP(e + 1, r, rh, f + 1, r) < r - f - 1) return false;
				return true;
			} else if(s[e] == s[f]) {
				if(diff >= t) return false;
			} else {
				return false;
			}
		}

		if(rh.LCP(l + lcp + 1, r, rh, l + t + lcp + 1, r) == r - lcp - 1 - t - l) return true;
		return false;
	};

	int q;
	cin >> q;
	rep(q) {
		int l, r;
		int t;
		cin >> l >> r >> t;
		l--;
		Yes(judge(l, r, t));
	}

	return 0;
}
accuracy: 0.05128205128205128
time_ms: 40
memory_kb: 4872
final_rank: 16

code_snippet: /*	author:  Kite_kuma
	created: 2021.08.16 12:53:59 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

class RollingHash_Mersenne {
	// safety rollinghash (mod : 1UL << 61 - 1, base : 10007 or random)
	// https://atcoder.jp/contests/agc047/submissions/16500504
	const unsigned long long MASK30 = (1ULL << 30) - 1;
	const unsigned long long MASK31 = (1ULL << 31) - 1;
	const unsigned long long MASK61 = (1ULL << 61) - 1;
	const unsigned long long MOD = MASK61;
	const unsigned long long base = 10007;	// 値が小さすぎると衝突しやすい
	const unsigned long long POSITIVIZER = MOD << 2;
	vector<unsigned long long> hash, power;

	// a * b と mod が等しい数を返す
	// 結果は (1UL << 63) + 3 - (1UL << 31) * 3 以下
	unsigned long long Mul(unsigned long long a, unsigned long long b) const {
		unsigned long long au = a >> 31;
		unsigned long long ad = a & MASK31;
		unsigned long long bu = b >> 31;
		unsigned long long bd = b & MASK31;
		unsigned long long mid = ad * bu + au * bd;
		unsigned long long midu = mid >> 30;
		unsigned long long midd = mid & MASK30;
		return au * bu * 2 + midu + (midd << 31) + ad * bd;
	}

	// mod 2^61-1を計算する
	unsigned long long CalcMod(unsigned long long x) const {
		unsigned long long xu = x >> 61;
		unsigned long long xd = x & MASK61;
		unsigned long long res = xu + xd;
		if(res >= MOD) res -= MOD;
		return res;
	}

   public:
	RollingHash_Mersenne() = default;
	RollingHash_Mersenne(const string &s, unsigned long long _base = 10007) : base(_base) {
		int sz = (int)s.size();
		hash.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for(int i = 0; i < sz; i++) {
			power[i + 1] = CalcMod(Mul(power[i], base));
			hash[i + 1] = CalcMod(Mul(hash[i], base) + s[i]);
		}
	}

	template <class T>
	RollingHash_Mersenne(const vector<T> &v, unsigned long long _base = 10007) : base(_base) {
		int sz = (int)v.size();
		hash.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for(int i = 0; i < sz; i++) {
			power[i + 1] = CalcMod(Mul(power[i], base));
			hash[i + 1] = CalcMod(Mul(hash[i], base) + v[i]);
		}
	}

	unsigned long long get(int l, int r) const { return CalcMod(hash[r] + POSITIVIZER - Mul(hash[l], power[r - l])); }

	unsigned long long connect(unsigned long long h1, unsigned long long h2, unsigned long long h2len) const {
		return CalcMod(Mul(h1, power[h2len]) + h2);
	}

	// Longest Common Prefix (using Binary Search)
	int LCP(int l_this, int r_this, RollingHash_Mersenne &other, int l_other, int r_other) {
		int len = min(r_this - l_this, r_other - l_other);
		int low = 0, high = len + 1;
		while(high - low > 1) {
			int mid = (low + high) / 2;
			if(get(l_this, l_this + mid) == other.get(l_other, l_other + mid))
				low = mid;
			else
				high = mid;
		}
		return low;
	}
};

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	STR(s);
	int n = s.size();
	RollingHash_Mersenne rh(s);

	auto judge = [&](int l, int r, int t) {
		if(t >= r - l) return true;
		int lcp = rh.LCP(l, r, rh, l + t, r);
		if(lcp >= r - l - t - 1) return true;

		int diff = l + lcp;
		int e = diff + t;
		int f = diff + t + t;

		assert(s[diff] != s[e]);

		if(f < r) {
			if(s[diff] == s[f]) {
				if(rh.LCP(diff + 1, e, rh, e + 1, f) < f - e - 1) return false;
				if(rh.LCP(e + 1, r, rh, f + 1, r) < r - f - 1) return false;
				return true;
			} else if(s[e] == s[f]) {
				if(diff >= t) return false;
			}else{
				return false;
			}
		}

		if(rh.LCP(l + lcp + 1, r, rh, l + t + lcp + 1, r) == r - lcp - 1 - t - l) return true;
		return false;
	};

	int q;
	cin >> q;
	rep(q) {
		int l, r;
		int t;
		cin >> l >> r >> t;
		l--;
		Yes(judge(l, r, t));
	}

	return 0;
}
accuracy: 0.05128205128205128
time_ms: 40
memory_kb: 4728
final_rank: 15

code_snippet: /*	author:  Kite_kuma
	created: 2021.08.16 12:53:59 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

class RollingHash_Mersenne {
	// safety rollinghash (mod : 1UL << 61 - 1, base : 10007 or random)
	// https://atcoder.jp/contests/agc047/submissions/16500504
	const unsigned long long MASK30 = (1ULL << 30) - 1;
	const unsigned long long MASK31 = (1ULL << 31) - 1;
	const unsigned long long MASK61 = (1ULL << 61) - 1;
	const unsigned long long MOD = MASK61;
	const unsigned long long base = 10007;	// 値が小さすぎると衝突しやすい
	const unsigned long long POSITIVIZER = MOD << 2;
	vector<unsigned long long> hash, power;

	// a * b と mod が等しい数を返す
	// 結果は (1UL << 63) + 3 - (1UL << 31) * 3 以下
	unsigned long long Mul(unsigned long long a, unsigned long long b) const {
		unsigned long long au = a >> 31;
		unsigned long long ad = a & MASK31;
		unsigned long long bu = b >> 31;
		unsigned long long bd = b & MASK31;
		unsigned long long mid = ad * bu + au * bd;
		unsigned long long midu = mid >> 30;
		unsigned long long midd = mid & MASK30;
		return au * bu * 2 + midu + (midd << 31) + ad * bd;
	}

	// mod 2^61-1を計算する
	unsigned long long CalcMod(unsigned long long x) const {
		unsigned long long xu = x >> 61;
		unsigned long long xd = x & MASK61;
		unsigned long long res = xu + xd;
		if(res >= MOD) res -= MOD;
		return res;
	}

   public:
	RollingHash_Mersenne() = default;
	RollingHash_Mersenne(const string &s, unsigned long long _base = 10007) : base(_base) {
		int sz = (int)s.size();
		hash.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for(int i = 0; i < sz; i++) {
			power[i + 1] = CalcMod(Mul(power[i], base));
			hash[i + 1] = CalcMod(Mul(hash[i], base) + s[i]);
		}
	}

	template <class T>
	RollingHash_Mersenne(const vector<T> &v, unsigned long long _base = 10007) : base(_base) {
		int sz = (int)v.size();
		hash.assign(sz + 1, 0);
		power.assign(sz + 1, 0);
		power[0] = 1;
		for(int i = 0; i < sz; i++) {
			power[i + 1] = CalcMod(Mul(power[i], base));
			hash[i + 1] = CalcMod(Mul(hash[i], base) + v[i]);
		}
	}

	unsigned long long get(int l, int r) const { return CalcMod(hash[r] + POSITIVIZER - Mul(hash[l], power[r - l])); }

	unsigned long long connect(unsigned long long h1, unsigned long long h2, unsigned long long h2len) const {
		return CalcMod(Mul(h1, power[h2len]) + h2);
	}

	// Longest Common Prefix (using Binary Search)
	int LCP(int l_this, int r_this, RollingHash_Mersenne &other, int l_other, int r_other) {
		int len = min(r_this - l_this, r_other - l_other);
		int low = 0, high = len + 1;
		while(high - low > 1) {
			int mid = (low + high) / 2;
			if(get(l_this, l_this + mid) == other.get(l_other, l_other + mid))
				low = mid;
			else
				high = mid;
		}
		return low;
	}
};

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	STR(s);
	int n = s.size();
	RollingHash_Mersenne rh(s);

	auto judge = [&](int l, int r, int t) {
		if(t >= r - l) return true;

		int lcp = rh.LCP(l, r, rh, l + t, r);
		if(lcp >= r - l - t - 1) return true;
		debug(l, r, t, lcp);
		int diff = l + lcp;
		int e = diff + t;
		int f = diff + t + t;
		if(f < n) {
			// if(s[e] != s[f] && s[diff] != s[f]) return false;
			if(s[diff] == s[f]) {
				// change e;
				if(rh.LCP(diff + 1, e, rh, e + 1, f) < f - e - 1) return false;
				if(rh.LCP(e + 1, r, rh, f + 1, r) < r - f - 1) return false;
				return true;
			} else if(s[e] == s[f]) {
				if(diff >= t) return false;
			}
		}

		if(rh.LCP(l + lcp + 1, r, rh, l + t + lcp + 1, r) == r - lcp - 1 - t - l) return true;

		// if(lcp < t) {
		// 	if(l + lcp + t * 2 < n && s [l + lcp + t * 2] != s[l + lcp]) return false;
		// 	if()
		// }
		return false;
	};

	int q;
	cin >> q;
	rep(q) {
		int l, r;
		int t;
		cin >> l >> r >> t;
		l--;
		Yes(judge(l, r, t));
	}

	return 0;
}
accuracy: 0.05128205128205128
time_ms: 40
memory_kb: 4656
final_rank: 14