编程一小时2023.5.12

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_set>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#define l first
#define r second

using namespace std;
typedef pair<int, int> PII;

string s1, s2;
vector<PII> intervals; 

typedef unsigned long long ULL;

const int N = 1e4 + 10;
int n, m;

class StringHash {
public:
explicit StringHash(string& str, int base=131) {
n = str.size();
this->base = base;
string s = "*" + str;
p[0] = 1;
for(int i = 1; i <= n; i++){
h[i] = h[i - 1]*base + s[i];
p[i] = p[i - 1]*base;
}
for(int i = n; i >= 1; i--) {
rev_h[i] = rev_h[i + 1]*base + s[i];
}
}

bool is_palindrome(int left, int right){
if(left > right) return true;
return shash(left, right) == shash(left, right, true);
}

vector<int> find(string& t) {
int m = t.size();
vector<int> pos;
if(m > n) return pos;
t = "*" + t;
ULL ht[N], pt[N];
pt[0] = 1;
for(int i = 1; i <= m; i++){
ht[i] = ht[i - 1]*base + t[i];
pt[i] = pt[i - 1]*base;
}
ULL h2 = ht[m] - ht[0]*pt[m];
for(int i = 1; i <= n - m + 1; i++) {
ULL h1 = shash(i, i + m - 1);
if(h1 == h2) pos.push_back(i - 1);
}
return pos;
}

ULL shash(int left, int right, bool is_rev=false) {
++left, ++right;
return is_rev? rev_h[left] - rev_h[right + 1]*p[right - left + 1]: h[right] - h[left - 1]*p[right - left + 1];
}

private:
int base, n;
ULL h[N], rev_h[N], p[N];
};

bool check(StringHash& sh1, StringHash& sh2, int len) {
unordered_set<ULL> us;
for(int l = 0; l + len - 1 < m; l++) {
int r = l + len - 1;
us.insert(sh2.shash(l, r));
}
for(auto&range: intervals) {
for(int l = range.l; l + len - 1 <= range.r; l++) {
int r = l + len - 1;
ULL hash_val = sh1.shash(l, r);
if(us.find(hash_val) != us.end()) return true;
}
}
return false;
}

int main() {
cin >> s1 >> s2;
n = s1.size(), m = s2.size();
int i = 0;
while(i < n && isdigit(s1[i])) i++;
while(i < n) {
int j = i;
while(j < n) {
if(j < n - 1) {
if(isalpha(s1[j + 1])) j++;
else break;
}else {
break;
}
}
if(j < n) {
intervals.push_back({i, j});
i = j + 1;
while(i < n && isdigit(s1[i])) i++;
}else {
break;
}
}
StringHash stringhash1(s1), stringhash2(s2);
int left = 0, right = min(n, m);
while(left < right) {
int mid = left + right + 1 >> 1;
if(check(stringhash1, stringhash2, mid)) {
left = mid;
}else {
right = mid - 1;
}
}
printf("%d", right);
return 0;
}

 

posted @   Verneyyx  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示