Untitled

 avatar
unknown
plain_text
a year ago
4.2 kB
5
Indexable
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define EPS 1e-9
#define mod 1000000007
// #define mod 998244353
#define over 10000000000
#define sz(m) (ll)(m.size())
#define ceil(n, m) (((n) / (m)) + ((n) % (m) ? 1 : 0))
#define fixed(n) fixed << setprecision(n)
const ll inf = 1e18 + 5;
template <typename T = int>
istream &operator>>(istream &in, vector<T> &v)
{
  for (T &i : v)
    in >> i;
  return in;
}
template <typename T = int>
ostream &operator<<(ostream &out, const vector<T> &v)
{
  for (const T &x : v)
    out << x << ' ';
  return out;
}

void lol()
{
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin), freopen("outputt.txt", "w", stdout), freopen("error.txt", "w", stderr);
#endif
}
double log(double base, double x)
{
  return (log(x) / log(base));
}

int dx[4] = {1, 0, 0, -1};
int dy[4] = {0, 1, -1, 0};

/////////////////////////////////////////////////////////
/* idea ->  segement tree and updata
  build tree for pre -> saving hashing value
  updata -> updata value in string -> updata valur in pre hasing
  ans -> get hashing value from (l -> r - x) == (l + x , r ) -> yes else no
*/

const int N = 1e5 + 5, p = 13;
ll tree[4 * N], lazy[4 * N], inv[N], pw[N], prepw[N];
string s;

int add(int a, int b)
{
  return (0LL + a % mod + b % mod + mod) % mod;
}

int mul(int a, int b)
{
  return (1LL * a % mod * b % mod) % mod;
}

int exp(int x, int n, int m)
{
  x %= m;
  int res = 1;
  while (n > 0)
  {
    if (n % 2 == 1)
    {
      res = mul(res, x);
    }
    x = mul(x, x);
    n /= 2;
  }
  return res % m;
}

void hashh()
{
  pw[0] = 1, inv[0] = 1;
  for (int i = 1; i <= N; i++)
  {
    pw[i] = mul(pw[i - 1], p);
    inv[i] = exp(pw[i], mod - 2, mod);
    prepw[i] = add(pw[i], prepw[i - 1]);
  }
}
void build(int node, int l, int r)
{
  if (l == r)
  {
    tree[node] = mul(s[l] - '0', pw[l]);
    return;
  }
  int mid = (l + r) / 2;
  build(node * 2, l, mid);
  build(node * 2 + 1, mid + 1, r);
  tree[node] = add(tree[node * 2], tree[node * 2 + 1]);
}
void update(int node, int l, int r, int l0, int rn, int val)
{

  if (lazy[node] != -1)
  {
    tree[node] = mul(lazy[node], add(prepw[r], l == 0 ? 0 : -prepw[l - 1]));
    if (l != r)
    {
      lazy[node * 2] = lazy[node];
      lazy[node * 2 + 1] = lazy[node];
    }
    lazy[node] = -1;
  }

  if (l0 > r || rn < l)
    return;

  if (l >= l0 && rn >= r)
  {
    tree[node] = mul(val, add(prepw[r], l == 0 ? 0 : -prepw[l - 1]));
    if (l != r)
    {
      lazy[node * 2] = val;
      lazy[2 * node + 1] = val;
    }
    return;
  }
  int mid = (l + r) / 2;
  update(2 * node, l, mid, l0, rn, val);
  update(2 * node + 1, mid + 1, r, l0, rn, val);
  tree[node] = add(tree[node * 2], tree[node * 2 + 1]);
}

int query(int node, int l, int r, int l0, int rn)
{

  if (lazy[node] != -1)
  {
    tree[node] = mul(lazy[node], add(prepw[r], l == 0 ? 0 : -prepw[l - 1]));
    if (l != r)
    {
      lazy[node * 2] = lazy[node];
      lazy[node * 2 + 1] = lazy[node];
    }
    lazy[node] = -1;
  }

  if (l0 > r || rn < l)
    return 0;
  if (l >= l0 && rn >= r)
    return tree[node];
  int mid = (l + r) / 2;
  return add(query(2 * node, l, mid, l0, rn), query(node * 2 + 1, mid + 1, r, l0, rn));
}
ll get_hash_range(int l, int r)
{
  return mul(query(1, l, r, 0, s.size() - 1), inv[l]);
}

int main()
{
  lol();
  int n, m, k;
  cin >> n >> m >> k;
  cin >> s;
  memset(lazy, -1, sizeof lazy);
  hashh();
  build(1, 0, s.size() - 1);
  int x =  m + k ; 
  while(x--){
  int op;
  cin >> op;
  if (op == 1)
  {
    int l, r, c;
    cin >> l >> r >> c;
    update(1, l - 1, r - 1, 0, s.size() - 1, c);
  }
  else
  {
    int l, r, d;
    cin >> l >> r >> d;
   //  cout << get_hash_range(l - 1, r - d - 1)  <<' ' <<  get_hash_range(l + d - 1, r - 1) <<'\n' ; 
    if (get_hash_range(l - 1, r - d - 1) == get_hash_range(l + d - 1, r - 1))
      cout << "YES" <<'\n' ;
    else
      cout << "NO" <<'\n' ;
  }
  }
}
Editor is loading...