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

Solution in C++ (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
#define MAX_N 100005

ull B=5575777;
ull mem[MAX_N];

ull pow(int x){
  assert(0<=x && x<MAX_N);

  if(x==0)return 1;
  if(mem[x]>0)return mem[x];
  if(x&1)return mem[x]=pow(x-1)*B;
  mem[x]=pow(x/2);
  mem[x]*=mem[x];
  return mem[x];
}

int n,q,l,r,t;
char s[MAX_N];
ull p[MAX_N];

ull get(int l,int r){
  if(l==r)return 0;

  return p[r]-p[l]*pow(r-l);
}

ull get(int l,int r,int x,char ch){
  if(l==r)return 0;

  ull res=p[r]-p[l]*pow(r-l);
  if(l<=x&&x<r){
    int dist=r-x-1;
    res-=pow(dist)*s[x];
    res+=pow(dist)*ch;
  }
  return res;
}

bool eq(int a,int b,int l,int r){
  assert(b-a==r-l);
  assert(a!=l);
  return ( get(a,b) == get(l,r) );
}

bool eq(int a,int b,int l,int r, int x,char ch){
  assert(b-a==r-l);
  assert(a!=l);
  return ( get(a,b,x,ch) == get(l,r,x,ch) );
}

bool calc(int a,int b,int l,int r){
  assert(b-a==r-l);
  assert(a!=l);

  if(b-a!=r-l)return false;
  int L=0,R=b-a+1,M;
  while(R-L>1){
    M=(L+R)/2;
    if( eq(a,a+M,l,l+M) ){
      L=M;
    }else{
      R=M;
    }
  }
  if(L==b-a)return true;
  return ( eq(a,b,l,r, l+L, s[a+L])  );
  //return ( eq(a,b,l,r, l+L, s[a+L]) || eq(a,b,l,r, a+L, s[l+L] )  );
}

bool intersect(int a,int b,int l,int r){
  if( b<=l || r<=a ) return false;
  else return true;
}

bool solve(){
  int len=r-l;
  if(t==len)return true;
  if(t*2>=len){
    return ( calc(l,l+(len-t),r-(len-t),r)   ||  calc(r-(len-t),r,l,l+(len-t)) );
  }


  if(len%t==0){
    return ( calc(l,r-t,l+t,r) || calc(l+t,r,l,r-t) );
  }
  int as=len%t;

  //  calc(l+as,r-t,l+as+t,r);
  //  if ( calc(l+as,r-t ,l+as+t,r) && ( eq(l,l+as,r-t,r-t+as) || eq(l,l+as,r-t-t,r-t-t+as) ) )return true;
  //if ( eq(l+as,r-t ,l+as+t,r) && ( calc(l,l+as,r-t,r-t+as) || calc(l,l+as,r-t-t,r-t-t+as) ) )return true;
 
  //if ( calc(l,r-as-t ,l+t,r-as) && (eq(l,l+as,r-as,r) ||eq(l+t,l+t+as,r-as,r) ) )return true;
  //if ( eq(l,r-as-t ,l+t,r-as) && ( calc(l,l+as,r-as,r) || calc(l+t,l+t+as,r-as,r) ) )return true;


  if ( calc(l,r-as-t ,l+t,r-as) && eq(l,l+as,r-as,r)  )return true;
  if ( calc(l+t,r-as ,l,r-as-t) && eq(l+t,l+t+as,r-as,r)  )return true;
  if ( eq(l,r-as-t ,l+t,r-as) && calc(l,l+as,r-as,r)  )return true;

  return false;
}

int main(){
  scanf("%s",s);
  n=strlen(s);

  p[0]=0;
  for(int i=1;i<=n;i++){
    p[i]=p[i-1]*B+s[i-1];
  }

  scanf("%d",&q);
  while(q--){
    scanf("%d %d %d",&l,&r,&t);

    l--;

    if(solve())printf("Yes\n");
    else printf("No\n");
  }
  return 0;
}