ACdream 1019 Palindrome 樹狀陣列+Hash
阿新 • • 發佈:2019-02-12
題目大意:
就是現在給出一個長度不超過100萬的字串, 有兩種操作, 修改某個位置的字元, 詢問 [L, R] 這個部分的字串是否是迴文串
大致思路:
這個題剛開始用線段樹寫了一發發現MLE...
然後就換樹狀陣列了...不知道zkw線段樹能不能行
首先對於這個串按照原來的順序和倒序分別建立樹狀陣列, 儲存每個字元對應在全部的串中對應的雜湊值
然後樹狀陣列查詢區間和, 修改的時候單點修改即可
整體複雜度O((n + Q)logn)
n表示字串長度
程式碼如下:
Result : Accepted Memory : 26092 KB Time : 1184 ms
/* * Author: Gatevin * Created Time: 2015/10/1 20:52:40 * File Name: A.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; typedef unsigned long long ulint; #define maxn 1000010 ulint seed = 23333uLL; ulint xp[maxn]; struct BIT { ulint c[maxn], N; inline int lowbit(int x) { return -x & x; } void add(int x, ulint val) { while(x <= N) c[x] += val, x += lowbit(x); } ulint sum(int x) { ulint ret = 0; while(x) ret += c[x], x -= lowbit(x); return ret; } void clear() { memset(c, 0, sizeof(c)); } }; BIT bit1, bit2; char s[maxn]; int len; bool check(int l, int r) { ulint val1 = bit1.sum(r) - bit1.sum(l - 1); ulint val2 = bit2.sum(len + 1 - l) - bit2.sum(len + 1 - r - 1); if(l < len + 1 - r) val2 *= xp[len + 1 - r - l]; else val1 *= xp[l - (len + 1 - r)]; return val1 == val2; } int main() { xp[0] = 1uLL; for(int i = 1; i <= 1000000; i++) xp[i] = xp[i - 1]*seed; while(scanf("%s", s + 1) != EOF) { len = strlen(s + 1); bit1.clear(); bit2.clear(); bit1.N = bit2.N = len; for(int i = 1; i <= len; i++) { bit1.add(i, (s[i] - 'a' + 1)*xp[len - i]); bit2.add(i, (s[len + 1 - i] - 'a' + 1)*xp[len - i]); } int Q; scanf("%d", &Q); char op[4]; while(Q--) { scanf("%s", op); if(op[0] == 'Q') { int l, r; scanf("%d %d", &l, &r); if(check(l, r)) puts("yes"); else puts("no"); } else { int pos; char c; scanf("%d %c", &pos, &c); bit1.add(pos, (c - s[pos])*xp[len - pos]); bit2.add(len + 1 - pos, (c - s[pos])*xp[len - (len + 1 - pos)]); s[pos] = c; } } } return 0; } /* aaaaa 4 Q 1 5 C 2 b Q 1 5 Q 1 3 */