Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// Lexicographically Minimum String Rotation
- int minlex(char* str){ /// Returns the 0-based index
- int i, j, k, n, len, x, y;
- len = n = strlen(str), n <<= 1, i = 0, j = 1, k = 0;
- while((i + k) < n && (j + k) < n) {
- x = i + k >= len ? str[i + k - len] : str[i + k];
- y = j + k >= len ? str[j + k - len] : str[j + k];
- if(x == y) k++;
- else if (x < y){
- j += ++k, k = 0;
- if (i >= j) j = i + 1;
- }
- else{
- i += ++k, k = 0;
- if (j >= i) i = j + 1;
- }
- }
- return (i < j) ? i : j;
- }
- int t;
- char str[50010];
- int main(){
- gets(str);
- while (gets(str)){
- printf("%d\n", minlex(str));
- }
- return 0;
- }
- /// Next palindrome
- #define MAX 100010
- char str[MAX];
- void next_palindrome(char* str){
- int i, j, k, l, x, n = strlen(str), carry = 1;
- for (i = 0, j = n - 1; j >= 0; i++, j--){
- if (carry){
- if (str[j] == 57) carry = 1, str[j] = 48;
- else carry = 0, str[j]++;
- }
- if (i > j) str[i] = str[j];
- else{
- if (str[i] < str[j]) carry = 1;
- str[j] = str[i];
- }
- }
- if (carry){
- str[n - 1] = 49;
- for (i = n - 1; i >= 0; i--) str[i + 1] = str[i];
- str[0] = 49, str[n + 1] = 0;
- }
- }
- int main(){
- int T = 0, t, i, j, k;
- scanf("%d", &t);
- while (t--){
- scanf("%s", str);
- next_palindrome(str);
- printf("Case %d: %s\n", ++T, str);
- }
- return 0;
- }
- /// Minimum palindromic factorization for all prefixes in O(N log N)
- #define MAX 1000010
- namespace pal{
- int pl[MAX][2], gpl[MAX][2];
- inline void set(int *ar, int x, int y, int z) {
- ar[0] = x, ar[1] = y, ar[2] = z;
- }
- inline void set(int ar[][2], int i, int v) {
- if (v > 0) ar[i][v & 1] = v;
- }
- inline void copy(int *A, int *B) {
- A[0] = B[0], A[1] = B[1], A[2] = B[2];
- }
- inline void update(int ar[][2], int i, int v) {
- if (v > 0 && (ar[i][v & 1] == -1 || ar[i][v & 1] > v)) ar[i][v & 1] = v;
- }
- /// Returns a vector v such that,
- /// v[i] is the minimum k so that the prefix string str[0:i] can be partitioned into k disjoint palindromes
- inline vector <int> factorize(const char* str){
- int g[32][3], gp[32][3], gpp[32][3];
- int i, j, k, l, d, u, r, x, pg = 0, pgp = 0, pgpp = 0, n = strlen(str);
- clr(g), clr(gp), clr(gpp);
- for (int i = 0; i < n; i++) gpl[i][0] = MAX, gpl[i][1] = MAX + 1;
- for (j = 0; j < n; j++){
- for (u = 0, pgp = 0; u < pg; u++){
- i = g[u][0];
- if ((i - 1) >= 0 && str[i - 1] == str[j]){
- g[u][0]--;
- copy(gp[pgp++], g[u]);
- }
- }
- pgpp = 0, r = -(j + 2);
- for (u = 0; u < pgp; u++){
- i = gp[u][0], d = gp[u][1], k = gp[u][2];
- if ((i - r) != d){
- set(gpp[pgpp++], i, i - r, 1);
- if (k > 1) set(gpp[pgpp++], i + d, d, k - 1);
- }
- else set(gpp[pgpp++], i, d, k);
- r = i + (k - 1) * d;
- }
- if (j - 1 >= 0 && str[j - 1] == str[j]){
- set(gpp[pgpp++], j - 1, j - 1 - r, 1);
- r = j - 1;
- }
- set(gpp[pgpp++], j, j - r, 1);
- int *ptr = gpp[0];
- for (u = 1, pg = 0; u < pgpp; u++){
- int *x = gpp[u];
- if (x[1] == ptr[1]) ptr[2] += x[2];
- else {
- copy(g[pg++], ptr);
- ptr = x;
- }
- }
- copy(g[pg++], ptr);
- pl[j + 1][(j & 1) ^ 1] = j + 1;
- pl[j + 1][j & 1] = MAX + (j & 1);
- for (u = 0; u < pg; u++){
- i = g[u][0], d = g[u][1], k = g[u][2];
- r = i + (k - 1) * d;
- update(pl, j + 1, pl[r][0] + 1);
- update(pl, j + 1, pl[r][1] + 1);
- if (k > 1) {
- update(pl, j + 1, gpl[i + 1 - d][0]);
- update(pl, j + 1, gpl[i + 1 - d][1]);
- }
- if (i + 1 >= d) {
- if (k > 1) {
- update(gpl, i + 1 - d, pl[r][0] + 1);
- update(gpl, i + 1 - d, pl[r][1] + 1);
- }
- else{
- set(gpl, i + 1 - d, pl[r][0] + 1);
- set(gpl, i + 1 - d, pl[r][1] + 1);
- }
- }
- }
- }
- vector <int> res(n, 0);
- for (i = 0; i < n; i++) res[i] = min(pl[i + 1][0], pl[i + 1][1]);
- return res;
- }
- }
- /// rope
- #define MAX 50010
- rope <char> R[MAX];
- int d = 0, ye = 0, vnow = 0;
- char str[105], out[10000010];
- int main(){
- int n, i, j, k, v, p, c, x, flag;
- while (scanf("%d", &n) != EOF){
- d = 0, vnow = 0;
- while (n--){
- scanf("%d", &flag);
- if (flag == 1){
- scanf("%d %s", &p, str);
- p -= d, vnow++;
- R[vnow] = R[vnow - 1];
- R[vnow].insert(p, str); /// Insert string str after position p
- }
- if (flag == 2){
- scanf("%d %d", &p, &c);
- p -= d, c -= d, vnow++;
- R[vnow] = R[vnow - 1];
- R[vnow].erase(p - 1, c); /// Remove c characters starting at position p
- }
- if (flag == 3){
- scanf("%d %d %d", &v, &p, &c); /// Print c characters starting at position p in version v
- v -= d, p -= d, c -= d;
- rope <char> sub = R[v].substr(p - 1, c); /// Get the substring of c characters from position p in version v
- for (auto it: sub){
- out[ye++] = it;
- if (it == 'c') d++;
- }
- out[ye++] = 10;
- }
- }
- }
- fwrite(out, 1, ye, stdout);
- return 0;
- }
- /// String Hash with Segment Tree
- /// Allows setting range with a character, querying hash of a range in O(log n)
- /// String functions uses 0-based index, however segment tree uses 1-based index
- namespace strhash{
- #define LET 10 /// Number of distinct letters in string, Set to digits [0-9] by default
- #define ADD 10007 /// Just another prime added randomly to get better hash values :)
- #define MAX 100010
- int P[2][MAX], RD[2][LET][MAX];
- int n, ar[MAX], lazy[MAX * 4];
- const int MOD[] = {2078526727, 2117566807};
- const int BASE[] = {1572872831, 1971536491};
- void build_tree(int idx, int a, int b);
- inline int getval(char ch){ /// Value of a character (without adding ADD)
- return ch - 48; /// Change this for lowercase or uppercase letters
- }
- void precalc(){ /// Call precalc() just once in whole program
- int i, j, k, d;
- P[0][0] = P[1][0] = 1;
- for (i = 1; i < MAX; i++){
- P[0][i] = ((long long) P[0][i - 1] * BASE[0]) % MOD[0];
- P[1][i] = ((long long) P[1][i - 1] * BASE[1]) % MOD[1];
- }
- for (i = 0; i < 2; i++){
- for (d = 0; d < LET; d++){
- k = ADD + d;
- long long x = 0;
- for (j = 1; j <= MAX; j++){
- x = ((x * BASE[i]) + k) % MOD[i];
- RD[i][d][j] = x;
- }
- }
- }
- }
- void init(char* str){
- n = strlen(str);
- for (int i = 0; i < n; i++) ar[i + 1] = getval(str[i]) + ADD;
- build_tree(1, 1, n);
- }
- struct Node{
- int H[2];
- inline Node(){
- }
- inline Node(int h1, int h2){
- H[0] = h1, H[1] = h2;
- }
- } tree[MAX << 2];
- inline void propagate(int idx, int a, int b){
- if (lazy[idx]){
- int p = (idx << 1), q = p + 1;
- int c = (a + b) >> 1, d = c + 1, val = lazy[idx];
- if (a != b){
- lazy[p] = lazy[q] = lazy[idx];
- tree[p] = Node(RD[0][val - ADD][c - a + 1], RD[1][val - ADD][c - a + 1]);
- tree[q] = Node(RD[0][val - ADD][b - d + 1], RD[1][val - ADD][b - d + 1]);
- }
- lazy[idx] = 0;
- }
- }
- inline void build_tree(int idx, int a, int b){
- lazy[idx] = 0;
- if (a == b){
- tree[idx].H[0] = tree[idx].H[1] = ar[a];
- return;
- }
- int p = (idx << 1), q = p + 1;
- int c = (a + b) >> 1, d = c + 1;
- build_tree(p, a, c);
- build_tree(q, d, b);
- tree[idx].H[0] = ((tree[p].H[0] * (long long) P[0][b - d + 1]) + tree[q].H[0]) % MOD[0];
- tree[idx].H[1] = ((tree[p].H[1] * (long long) P[1][b - d + 1]) + tree[q].H[1]) % MOD[1];
- }
- inline void update(int idx, int a, int b, int l, int r, int val){
- if (a == l && b == r){
- lazy[idx] = val;
- tree[idx] = Node(RD[0][val - ADD][b - a + 1], RD[1][val - ADD][b - a + 1]);
- propagate(idx, a, b);
- return;
- }
- propagate(idx, a, b);
- int p = (idx << 1), q = p + 1;
- int c = (a + b) >> 1, d = c + 1;
- if (r <= c) update(p, a, c, l, r, val);
- else if (l >= d) update(q, d, b, l, r, val);
- else{
- update(p, a, c, l, c, val);
- update(q, d, b, d, r, val);
- }
- tree[idx].H[0] = ((tree[p].H[0] * (long long) P[0][b - d + 1]) + tree[q].H[0]) % MOD[0];
- tree[idx].H[1] = ((tree[p].H[1] * (long long) P[1][b - d + 1]) + tree[q].H[1]) % MOD[1];
- }
- inline Node query(int idx, int a, int b, int l, int r){
- propagate(idx, a, b);
- int p = (idx << 1), q = p + 1;
- int c = (a + b) >> 1, d = c + 1;
- if (a == l && b == r) return tree[idx];
- if (r <= c) return query(p, a, c, l, r);
- else if (l >= d) return query(q, d, b, l, r);
- else{
- Node x = query(p, a, c, l, c);
- Node y = query(q, d, b, d, r);
- for (int i = 0; i < 2; i++){
- x.H[i] = ((P[i][r - d + 1] * (long long) x.H[i]) + y.H[i]) % MOD[i];
- }
- return x;
- }
- }
- /// Note 0-based index used for string update and gethash
- inline void update(int l, int r, char ch){ /// Sets the sub-string in str[l:r] to ch
- update(1, 1, n, ++l, ++r, getval(ch) + ADD);
- }
- inline long long gethash(int l, int r){
- Node h = query(1, 1, n, ++l, ++r);
- return (h.H[0] << 32) | h.H[1];
- }
- }
- /// Double Hashing
- struct simplehash{
- int len;
- long long base, mod;
- vector <int> P, H, R;
- simplehash(){}
- simplehash(const char* str, long long b, long long m){
- base = b, mod = m, len = strlen(str);
- P.resize(len + 3, 1), H.resize(len + 3, 0), R.resize(len + 3, 0);
- for (int i = 1; i <= len; i++) P[i] = (P[i - 1] * base) % mod;
- for (int i = 1; i <= len; i++) H[i] = (H[i - 1] * base + str[i - 1] + 1007) % mod;
- for (int i = len; i >= 1; i--) R[i] = (R[i + 1] * base + str[i - 1] + 1007) % mod;
- }
- inline int range_hash(int l, int r){
- int hashval = H[r + 1] - ((long long)P[r - l + 1] * H[l] % mod);
- return (hashval < 0 ? hashval + mod : hashval);
- }
- inline int reverse_hash(int l, int r){;
- int hashval = R[l + 1] - ((long long)P[r - l + 1] * R[r + 2] % mod);
- return (hashval < 0 ? hashval + mod : hashval);
- }
- };
- struct stringhash{
- simplehash sh1, sh2;
- stringhash(){}
- stringhash(const char* str){
- sh1 = simplehash(str, 1949313259, 2091573227);
- sh2 = simplehash(str, 1997293877, 2117566807);
- }
- inline long long range_hash(int l, int r){
- return ((long long)sh1.range_hash(l, r) << 32) ^ sh2.range_hash(l, r);
- }
- inline long long reverse_hash(int l, int r){
- return ((long long)sh1.reverse_hash(l, r) << 32) ^ sh2.reverse_hash(l, r);
- }
- };
- /// Bit string LCS
- #include <time.h>
- #define MAX 100010
- bool flag[MAX];
- char A[MAX], B[MAX], S[2][MAX];
- int lcs(char* A, char* B){
- int i, j, k, v, n, m, res = 0;
- unsigned long long x, t, q, y, mask[128] = {0};
- memset(flag, 0, sizeof(flag));
- for (n = 0; A[n]; n++) S[0][n] = A[n];
- for (m = 0; B[m]; m++) S[1][m] = B[m];
- for (i = 0; (i * 64) < m; i++){
- memset(mask, 0, sizeof(mask));
- for (k = 0; k < 64 && (i * 64 + k) < m; k++){
- mask[S[1][i * 64 + k]] |= (1ULL << k);
- }
- for (j = 0, x = 0; j < n; j++){
- t = mask[S[0][j]] & ~x;
- x |= t, v = flag[j];
- q = x - (t << 1) - v, y = (q & ~x) | t;
- flag[j] = y >> 63, x &= ~(y << 1);
- if (v) x &= ~1ULL;
- }
- res += __builtin_popcountll(x);
- }
- return res;
- }
- int main(){
- int i, j, k, n, m;
- n = MAX - 10, m = MAX - 10;
- for (i = 0; i < n; i++) A[i] = (rand() % 26) + 'a';
- for (i = 0; i < m; i++) B[i] = (rand() % 26) + 'a';
- A[n] = B[m] = 0;
- clock_t start = clock();
- printf("%d\n", lcs(A, B));
- printf("%0.6f\n", (clock() - start) / (1.0 * CLOCKS_PER_SEC));
- return 0;
- }
- /// 2D Pattern Matcher
- const unsigned long long base = 1995433697ULL;
- const unsigned long long fuck = 1000000007ULL;
- int n, m, r, c;
- char str[2010][2010], pattern[2010][2010];
- unsigned long long pattern_hash, P[2010], F[2010], ar[2010];
- void Pregenerate(){
- int i, j;
- pattern_hash = 0;
- for (i = 0; i < r; i++){
- unsigned long long res = 0;
- for (j = 0; j < c; j++) res = (res * fuck) + pattern[i][j];
- pattern_hash = (pattern_hash * base) + res;
- }
- }
- int Solve(){
- int i, j, res = 0;
- unsigned long long x = 0, y;
- for (i = 0; i < r; i++) x = (x * base) + ar[i];
- for (i = 0; i < n; i++){
- if ((i + r) > n) break;
- if (x == pattern_hash) res++;
- y = (x - (P[r - 1] * ar[i]));
- x = (y * base) + ar[i + r];
- }
- return res;
- }
- int main(){
- int i, j, k, l;
- P[0] = F[0] = 1;
- for (i = 1; i < 2010; i++){
- P[i] = P[i - 1] * base;
- F[i] = F[i - 1] * fuck;
- }
- while (scanf("%d %d %d %d", &r, &c, &n, &m) != EOF){
- for (i = 0; i < r; i++) scanf("%s", pattern[i]);
- for (i = 0; i < n; i++) scanf("%s", str[i]);
- int res = 0;
- Pregenerate();
- for (i = 0; i < n; i++){
- unsigned long long res = 0;
- for (j = 0; j < c; j++) res = (res * fuck) + str[i][j];
- ar[i] = res;
- }
- for (j = 0; j < m; j++){
- if ((j + c) > m) break;
- res += Solve();
- for (i = 0; i < n; i++){
- unsigned long long x = ar[i];
- x = x - (F[c - 1] * str[i][j]);
- ar[i] = (x * fuck) + str[i][j + c];
- }
- }
- printf("%d\n", res);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment