【线段树+HASH】CODEFORCES 580E Kefa and Watch
题意:0-9字符串,区间修改,区间询问是否d周期
思路:直接暴力线段树,然后HASH修改和查询,卡HASH的话就双HASH。
代码:
#include<cstdio> #include<cstring> typedef long long ll; const int N = 100007; int n, m, k, lens; char s[N]; #define lch id<<1 #define rch id<<1|1 class HashTree{ public: int mod, p; ll powp[N], sump[N]; void getpowp(){ powp[0] = 1; sump[0] = 1; for(int i = 1; i < N; i++){ powp[i] = powp[i-1] * p; if(powp[i] >= mod) powp[i] %= mod; sump[i] = sump[i-1] + powp[i]; if(sump[i] >= mod) sump[i] %= mod; } } ll v[N << 2]; int len[N << 2]; char lazy[N << 2]; void plant(int id,int l,int r){ lazy[id] = '\0'; if(l == r){ v[id] = s[l]; len[id] = 1; return; } int mid = (l + r) >> 1; plant(lch, l, mid); plant(rch, mid + 1, r); len[id] = len[lch] + len[rch]; v[id] = v[lch] * powp[len[rch]] + v[rch]; if(v[id] >= mod) v[id] %= mod; } void pushdown(int id){ if(lazy[id] != '\0'){ lazy[lch] = lazy[rch] = lazy[id]; v[lch] = lazy[id] * sump[len[lch] - 1]; if(v[lch] >= mod) v[lch] %= mod; v[rch] = lazy[id] * sump[len[rch] - 1]; if(v[rch] >= mod) v[rch] %= mod; lazy[id] = '\0'; } } void update(int id,int ql,int qr,int l,int r,char c){ if(ql == l && qr == r){ lazy[id] = c; v[id] = c * sump[len[id] - 1]; if(v[id] >= mod) v[id] %= mod; return; } pushdown(id); int mid = (l + r) >> 1; if(qr <= mid) update(lch, ql, qr, l, mid, c); else if(mid < ql) update(rch, ql, qr, mid + 1, r, c); else update(lch, ql, mid, l, mid, c), update(rch, mid + 1, qr, mid + 1, r, c); v[id] = v[lch] * powp[len[rch]] + v[rch]; if(v[id] >= mod) v[id] %= mod; } ll query(int id,int ql,int qr,int l,int r){ if(ql == l && qr == r){ return v[id]; } pushdown(id); int mid = (l + r) >> 1; if(qr <= mid) return query(lch, ql, qr, l, mid); else if(mid < ql) return query(rch, ql, qr, mid + 1, r); else{ ll t1 = query(lch, ql, mid, l, mid); ll t2 = query(rch, mid + 1, qr, mid + 1, r); ll t = t1 * powp[qr - (mid + 1) + 1] + t2; if(t >= mod) t %= mod; return t; } } }tree1, tree2; bool equal(int l1, int r1, int l2, int r2){ if(tree1.query(1, l1, r1, 0, lens - 1) != tree1.query(1, l2, r2, 0, lens - 1)) return false; if(tree2.query(1, l1, r1, 0, lens - 1) != tree2.query(1, l2, r2, 0, lens - 1)) return false; return true; } bool judge(int l, int r, int d){ if(r - l + 1 == d) return true; int l2 = l + d, r2 = r; int l1 = l, r1 = r - d; return equal(l1, r1, l2, r2); } int main(){ tree1.mod = 1e9 + 7, tree1.p = 799817, tree1.getpowp(); tree2.mod = 1e9 + 9, tree2.p = 451309, tree2.getpowp(); scanf("%d%d%d",&n,&m,&k); scanf("%s",s); lens = (int)strlen(s); tree1.plant(1, 0, lens - 1), tree2.plant(1, 0, lens - 1); for(int i = 1; i <= m + k; i++){ int ty, l, r; scanf("%d%d%d",&ty,&l,&r); l--, r--; if(ty == 1){ char c[5]; scanf("%s",c); tree1.update(1, l, r, 0, lens - 1, c[0]); tree2.update(1, l, r, 0, lens - 1, c[0]); } else{ int d; scanf("%d",&d); printf("%s\n", judge(l, r, d) ? "YES" : "NO"); } } return 0; }