UVALive - 7041 The Problem to Slow Down You (回文树)

https://vjudge.net/problem/UVALive-7041

题意

给出两个仅包含小写字符的字符串 A 和 B ; 
求:对于 A 中的每个回文子串,B 中和该子串相同的子串个数的总和。

分析

从0和1两个根节点DFS下去,如果两个相同的节点同时存在就统计答案。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
//#define eps 0.0000000001
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define random(a, b) rand()*rand()%(b-a+1)+a
#define pi acos(-1)
//const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 10;
const int maxm = 3000000 +10;
const int mod = 1000000007;

struct PAM{
    int nxt[maxn][26];
    int fail[maxn];
    int cnt[maxn];
    int num[maxn];
    int len[maxn];
    int s[maxn];
    int last,n,p;

    int newnode(int w){
        for(int i=0;i<26;i++) nxt[p][i]=0;
        num[p]=cnt[p]=0;
        len[p]=w;
        return p++;
    }
    void init(){
        n=last=p=0;
        newnode(0);
        newnode(-1);
        s[n]=-1;
        fail[0]=1;
    }
    int get_fail(int x){
        while(s[n-len[x]-1]!=s[n]) x=fail[x];
        return x;
    }
    void add(int c){
        c-=‘a‘;
        s[++n]=c;
        int cur=get_fail(last);
        if(!nxt[cur][c]){
            int now=newnode(len[cur]+2);
            fail[now]=nxt[get_fail(fail[cur])][c];
            nxt[cur][c]=now;
            num[now]=num[fail[now]]+1;
        }
        last=nxt[cur][c];
        cnt[last]++;
    }
    void Count(){
        for(int i=p-1;i>=0;i--) cnt[fail[i]]+=cnt[i];
    }
};
PAM pam1,pam2;
char a[maxn],b[maxn];
ll dfs(int an,int bn){
    ll res=0;
    for(int i=0;i<26;i++)
        if(pam1.nxt[an][i]!=0&&pam2.nxt[bn][i]!=0){
            res+=(ll)pam1.cnt[pam1.nxt[an][i]]*pam2.cnt[pam2.nxt[bn][i]]+dfs(pam1.nxt[an][i],pam2.nxt[bn][i]);
        }
    return res;
}
int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//    freopen("input.txt", "w", stdout);
#endif
    int T,cas=1;
    scanf("%d",&T);

    while(T--){
        pam1.init();
        pam2.init();
        scanf("%s%s",a,b);
        int l1=strlen(a),l2=strlen(b);
        for(int i=0;i<l1;i++) pam1.add(a[i]);
        for(int i=0;i<l2;i++) pam2.add(b[i]);
        pam1.Count();
        pam2.Count();
        ll ans=dfs(0,0)+dfs(1,1);
        printf("Case #%d: %lld\n",cas++,ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/fht-litost/p/9594584.html

时间: 2024-07-30 03:06:34

UVALive - 7041 The Problem to Slow Down You (回文树)的相关文章

codeforces Gym 100548G - The Problem to Slow Down You 回文树

直接从两棵树的奇根和偶根dfs就可以了. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<map> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using names

三. Anagram detection problem for string(字符串中回文词汇检测问题)

anagram 相同字母异序词.heart vs earth 1.Our first solution to the anagram problem will check to see that each character in the first string actually occurs in the second. If it is possible to "checkoff" each character, then the two strings must be anag

Gym - 101981M:(南京) Mediocre String Problem(回文树+exkmp)

#include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=1000010; char S[maxn],T[maxn]; struct PT { struct in{ int dep,fail,len,son[26]; }p[maxn]; int cnt,last; void init() { //mems

2016中国大学生程序设计竞赛(长春)-重现赛 1010Ugly Problem 回文数 模拟

Ugly Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0Special Judge Problem Description Everyone hates ugly problems. You are given a positive integer. You m

HDU 5371 Hotaru&#39;s problem (Manacher,回文串)

题意:给一个序列,找出1个连续子序列,将其平分成前,中,后等长的3段子序列,要求[前]和[中]是回文,[中]和[后]是回文.求3段最长为多少?由于平分的关系,所以答案应该是3的倍数. 思路:先Manacher求最长子串,利用期间所记录的P 数组,穷举一下所有可能的前两串,再用O(1)时间判断第3串是否符合要求. 具体做法: (1)P[i]记录的是以i为中心,从i-P[i]+1到i+P[i]-1这段都是回文.由于前两段之和必为偶数,所以必须选取str[i]为'#'的. (2)扫一遍每个'#',以其

Petrozavodsk Winter-2013. Ural FU Contest Problem D. Five Palindromes manacher、一个串切割成5个回文子串、优化

Ural Federal University Contest, SKB Kontur Cup Petrozavodsk Winter Training Camp, Saturday, February 2, 2013 Problem D. Five Palindromes Input file: input.txt Output file: output.txt Time limit: 2 seconds (3 seconds for Java) Memory limit: 256 mebib

LeetCode Problem 9:Palindrome Number回文数

描述:Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could negative integers be palindromes? (ie, -1) If you are thinking of converting the integer to string, note the restriction of using extra space. You could a

HDU 5371——Hotaru&#39;s problem——————【manacher处理回文】

Hotaru's problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1765    Accepted Submission(s): 635 Problem Description Hotaru Ichijou recently is addicated to math problems. Now she is playing

HDU 5371(2015多校7)-Hotaru&#39;s problem(Manacher算法求回文串)

题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列,该子序列分为三部分,第一部分与第三部分相同,第一部分与第二部分对称,如果存在求最长的符合这种条件的序列. 思路:用Manacher算法来处理回文串的长度,记录下以每一个-1(Manacher算法的插入)为中心的最大回文串的长度.然后从最大的开始穷举,只要p[i]-1即能得出以数字为中心的最大回文串的长度,然后找到右边对应的'-1',判断p[i]是不是大于所穷举的长度,如果当前的满足三段,那么就跳出,继续