[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
原文地址:https://www.cnblogs.com/mrclr/p/9548711.html