zoukankan      html  css  js  c++  java
  • [Baltic2014]friends

    嘟嘟嘟

    首先想想暴力的做法,枚举加入的字符,然后判断删去这个字符后两个长度为n / 2的字符串是否相等,复杂度O(n2)。

    所以可以想办法把判断复杂度降低到O(1),那自然就想到hash了。hash是能做到O(n)预处理,然后O(1)比较的。

    取一段的hash值:hash[L, R] = hash[1, R] - hash[1, L - 1] * baseR - L + 1.这个也好理解,就是前面的hash[1, L - 1]为整个hash值贡献了hash[1, L - 1] * baseR - L + 1,减去即可。

    思路就这么明显~~只不过合并hash值得时候得想清楚了……

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a) memset(a, 0, sizeof(a))
    15 typedef long long ll;
    16 typedef unsigned long long ull;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const ull base = 19260817;
    20 const int eps = 1e-8;
    21 const int maxn = 2e6  + 5;
    22 inline ll read()
    23 {
    24     ll ans = 0;
    25     char ch = getchar(), last = ' ';
    26     while(!isdigit(ch)) {last = ch; ch = getchar();}
    27     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    28     if(last == '-') ans = -ans;
    29     return ans;
    30 }
    31 inline void write(ll x)
    32 {
    33     if(x < 0) x = -x, putchar('-');
    34     if(x >= 10) write(x / 10);
    35     putchar(x % 10 + '0');
    36 }
    37 
    38 int n, mid;
    39 char s[maxn];
    40 ull has[maxn], f[maxn], las = 0;
    41 int del, tot = 0;
    42 
    43 ull get(int L, int R)
    44 {
    45     return has[R] - has[L - 1] * f[R - L + 1];
    46 }
    47 int judge(int x)
    48 {
    49     ull h1, h2;
    50     if(x < mid)
    51     {
    52         h1 = get(1, x - 1) * f[mid - x] + get(x + 1, mid);
    53         h2 = get(mid + 1, n);
    54     }
    55     else if(x > mid)
    56     {
    57         h1 = get(1, mid - 1);
    58         h2 = get(mid, x - 1) * f[n - x] + get(x + 1, n);
    59     }
    60     else
    61     {
    62         h1 = get(1, x - 1);
    63         h2 = get(x + 1, n);
    64     }
    65     if(h1 == h2)
    66     {
    67         del = x;
    68         if(h1 == las) return 0;    
    69         las = h1; return 1;
    70     }
    71     return 0;
    72 }
    73 
    74 int main()
    75 {
    76     n = read(); scanf("%s", s + 1);
    77     if(!(n & 1)) {puts("NOT POSSIBLE"); return 0;}
    78     f[0] = 1;
    79     for(int i = 1; i <= n; ++i) f[i] = f[i - 1] * base;
    80     for(int i = 1; i <= n; ++i) has[i] = has[i - 1] * base + s[i] - 'A' + 1;
    81     mid = (n >> 1) + 1;
    82     for(int i = 1; i <= n; ++i) tot += judge(i);
    83     if(!tot) puts("NOT POSSIBLE");
    84     else if(tot > 1) puts("NOT UNIQUE");
    85     else 
    86     {
    87         for(int i = 1, cnt = 1; cnt <= (n >> 1); ++i, cnt++)
    88         {
    89             if(i == del) cnt--;
    90             else putchar(s[i]);
    91         }
    92         enter;
    93     }
    94         return 0;
    95 }
    View Code
  • 相关阅读:
    Clustering by fast search and find of density peaks
    《第一行代码》(二)
    TF-IDF
    《第一行代码》(一)
    《OpenCV入门》(三)
    OpenCV入门(二)
    协方差矩阵特征向量的意义
    ICA
    整数划分
    1144. The Missing Number (20)
  • 原文地址:https://www.cnblogs.com/mrclr/p/9548711.html
Copyright © 2011-2022 走看看