2014-2015 ACM-ICPC, Asia Xian Regional Contest(G - The Problem to Slow Down You-回文树)

来源:互联网 发布:cocos2dx for mac 编辑:程序博客网 时间:2024/04/30 01:44

求两个字符串的公共回文子序列个数

建立2个回文树,统计2个字符串每个本质不同的回文串个数,
然后同时遍历2个回文树(取交),或者hash什么的都行

#include<bits/stdc++.h>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F1 (3000000009uLL)#define F2 (1000000000000000000000000000000uLL) #define pb push_back#define mp make_pair #define fi first#define se second#define MAXN (300000+10)typedef long long ll;typedef unsigned long long ull;const ull base=300007uLL;const ull base2=500009uLL;map<pair<ull,ull> ,int> h;map<pair<ull,ull> ,int>::iterator it;namespace Palindromic_Tree {    int s[MAXN],n;    int tot,next[MAXN][26],link[MAXN],len[MAXN],last;    int cnt[MAXN];    int newnode(int l)    {        len[tot]=l;        return tot++;    }    void mem(int N) {        Rep(i,N) cnt[i]=0,MEM(next[i]);//      MEM(s) MEM(next) MEM(link) MEM(len) MEM(cnt)        n=tot=0;        newnode(0); newnode(-1);        link[0]=link[1]=1; s[0]=27;        last=0;    }    int getnode(int x)    {        while (s[ n - len[x]-1 ]  != s[n] ) x=link[x];        return x;     }    void add(int c) {        s[++n]=c;        int cur=getnode(last);        if (!next[cur][c])        {            int now=newnode(len[cur]+2);            int tmp=getnode(link[cur]);            link[now]=next[tmp][c];            next[cur][c] = now;        }               last=next[cur][c];        cnt[last]++;    }    ull h1[MAXN],h2[MAXN];    void dfs()    {        Rep(x,tot) {            ull p1=h1[x],p2=h2[x];            Rep(c,26) {                if (next[x][c]) h1[next[x][c]]=(p1*base+1+c)%F1,h2[next[x][c]]=(p2*base2+1+c)%F2;             }             if (x==0||x==1) ;             else{                h[mp(h1[x],h2[x])]=cnt[x];              }         }     }    void work()    {        RepD(i,tot-1) cnt[link[i]]+=cnt[i];        h1[0]=h2[0]=21,h1[1]=h2[1]=12;        dfs();    }    bool b[MAXN];    ll _ans;    void dfs2()    {        Rep(x,tot) b[x]=0; b[0]=b[1]=1;         Rep(x,tot) {            if (!b[x]) continue;            ull p1=h1[x],p2=h2[x];            it = h.find(mp(p1,p2));            if (x>1&&it==h.end()) continue ;                else if (x>1) {                    _ans+=(ll)(*it).se*(ll)cnt[x]; //                  cout<< (*it).se <<' '<< cnt[x] <<endl;                }                Rep(c,26) {                    if (next[x][c])                     {                        b[next[x][c]]=1;                        h1[next[x][c]]=(p1*base+1+c)%F1,h2[next[x][c]]=(p2*base2+1+c)%F2;                     }            }          }     }    void work2()    {         RepD(i,tot-1) cnt[link[i]]+=cnt[i];        h1[0]=h2[0]=21,h1[1]=h2[1]=12;        _ans=0;        dfs2();        cout<<_ans<<endl;    }}using namespace Palindromic_Tree;char S[MAXN];int N;int main(){//  freopen("CF100548G_data.in","r",stdin);//  freopen(".out","w",stdout);    int T; cin>>T;    For(kcase,T)    {         h.clear();        scanf("%s",S);        int N=strlen(S);        Palindromic_Tree::mem(N+6);        Rep(i,N) Palindromic_Tree::add(S[i]-'a');        Palindromic_Tree::work();         scanf("%s",S);        N=strlen(S);        Palindromic_Tree::mem(N+6);        Rep(i,N) Palindromic_Tree::add(S[i]-'a');        printf("Case #%d: ",kcase);        Palindromic_Tree::work2();     }    return 0;}
0 0
原创粉丝点击