字符串hash+线段树
题意:给一个字符串(<=1e5), 进行操作和查询(<=1e5)。
1)将指定位置的字符改为c
2)询问l-r的子串,是否是回文串。
解法 :区间维护pl和pr,表示从左到右的hash和从右到左的hash,然后在up和query中合并区间,最后判断pl和pr是否相等即可。
#include <cstdio> #include <ctime> #include <cstdlib> #include <cstring> #include <queue> #include <string> #include <set> #include <stack> #include <map> #include <cmath> #include <vector> #include <iostream> #include <algorithm> #include <bitset> #include <fstream> using namespace std; //LOOP #define FF(i, a, b) for(int i = (a); i < (b); ++i) #define FE(i, a, b) for(int i = (a); i <= (b); ++i) #define FED(i, b, a) for(int i = (b); i>= (a); --i) #define REP(i, N) for(int i = 0; i < (N); ++i) #define CLR(A,value) memset(A,value,sizeof(A)) #define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++) //OTHER #define SZ(V) (int)V.size() #define PB push_back #define MP make_pair #define all(x) (x).begin(),(x).end() //INPUT #define RI(n) scanf("%d", &n) #define RII(n, m) scanf("%d%d", &n, &m) #define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k) #define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p) #define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q) #define RS(s) scanf("%s", s) #define sqr(x) (x) * (x) typedef long long LL; typedef unsigned long long ULL; typedef vector <int> VI; const int INF = 0x3f3f3f3f; const double EPS = 1e-9; const int MOD = 1000000007; const double PI = acos(-1.0); const int maxn = 100100; #define ll rt << 1 #define rr rt << 1 | 1 const int SEED = 13331; ULL P[maxn + 10]; char s[maxn]; void hash_pre(ULL P[]) { P[0] = 1; for (int i = 1; i <= maxn; i++) P[i] = P[i - 1] * SEED; } struct HashNode{ ULL pl, pr; HashNode(){} HashNode(ULL pl, ULL pr) : pl(pl), pr(pr){} }qans; struct Node{ int l, r, m; ULL pl, pr; }st[maxn << 2]; inline void up(int rt) { st[rt].pl = st[ll].pl * P[st[rt].r - st[rt].m] + st[rr].pl; st[rt].pr = st[rr].pr * P[st[rt].m - st[rt].l + 1] + st[ll].pr; } void build(int l, int r, int rt) { st[rt].l = l ;st[rt].r = r; int m = (l + r) >> 1; st[rt].m = m; if (l == r) { st[rt].pl = st[rt].pr = s[l - 1]; return; } build(l, m, ll); build(m + 1, r, rr); up(rt); } void update(int x, char c, int rt) { if (st[rt].l == st[rt].r) { st[rt].pl = st[rt].pr = c; return ; } if (x <= st[rt].m) update(x, c, ll); else update(x, c, rr); up(rt); } inline HashNode gettmp(HashNode tmp1, HashNode tmp2, int l, int r, int m) { HashNode tmp; tmp.pl = tmp1.pl * P[r - m] + tmp2.pl; tmp.pr = tmp2.pr * P[m - l + 1] + tmp1.pr; return tmp; } HashNode query(int L, int R, int rt) { if (L <= st[rt].l && st[rt].r <= R) { return HashNode(st[rt].pl, st[rt].pr); } if (R <= st[rt].m) return query(L, R, ll); else if (L > st[rt].m) return query(L, R, rr); else { HashNode tmp1 = query(L, R, ll); HashNode tmp2 = query(L, R, rr); return gettmp(tmp1, tmp2, max(L, st[rt].l), min(R, st[rt].r), st[rt].m); } } char ss[110]; int main() { hash_pre(P); int n, q; while (~RS(s)) { n = strlen(s); build(1, n, 1); RI(q); while (q--) { RS(ss); if (ss[0] == 'c') { int x; char c; RI(x); scanf(" %c", &c); update(x, c, 1); } else { int x, y; RII(x, y); qans = query(x, y, 1); if (qans.pl == qans.pr) puts("Yes"); else puts("No"); } } } return 0; }
bnu36907 Subpalindromes 字符串hash+线段树,布布扣,bubuko.com
bnu36907 Subpalindromes 字符串hash+线段树
原文地址:http://blog.csdn.net/guognib/article/details/38497285