回文树模板 2018 icpc南京站网络赛 I. Skr

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ccsu_cat/article/details/83622879

引用:

Palindromic Tree——回文树【处理一类回文串问题的强力工具】

回文树练习

代码取自:回文树代码模板

#include "cstdio"
#include "algorithm"
#include "cstring"
#define maxn 10000005
#define sigma 26
struct ptree{
    char s[maxn];
    int next[maxn][sigma],fail[maxn],cnt[maxn],len[maxn];
    int last,n,p;
    long long res;
    inline int newnode(int l){
        cnt[p]=0;
        len[p]=l;
        return p++;
    }
    inline void init(){
        newnode(0),newnode(-1);//two roots
        s[n]=-1;
        fail[0]=1;
    }
    inline int FL(int x){
        while(s[n-len[x]-1]!=s[n]) x=fail[x];
        return x;
    }
    void add(char c){
        c-='a';
        s[++n]=c;
        int cur=FL(last);
        if(!next[cur][c]){
            int now=newnode(len[cur]+2);
            fail[now]=next[FL(fail[cur])][c];
            next[cur][c]=now;
        }
        last=next[cur][c];
        ++cnt[last];
    }
    inline unsigned long long count(){
        unsigned long long pk=0;
        for(int i=p-1;~i;--i){
            cnt[fail[i]]+=cnt[i];
            pk+=((unsigned long long)cnt[i])*len[i];
        }
        return pk;
    }
} p;
char s[maxn];
int i,j,k;
int main(){
    scanf("%s",s);
    j=strlen(s);
    p.init();
    for(i=0;i<j;++i) p.add(s[i]);
    printf("%llu\n",p.count());
    return 0;
}

I.Skr

题意:给你一个数字串,求所有本质不同的回文数字串的和%1e9+7

学会回文树后,这题就变成水题了,只需在每次插入的时候,如果插入的是一个新节点,那么新节点num代表的数字可以由父亲*10+num*10^(len-1)+num得到,然后加到答案即可,len表示这个节点代表的回文数字串的长度。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=1e9+7,maxn=2e6+10;
ll ans=0,po[maxn];
struct pal
{
	char s[maxn];
	int next[maxn][10],fail[maxn],len[maxn];
	int last,n,p;
	ll res[maxn];
	int newnode(int l)
	{
		len[p]=l;
		return p++;
	}
	void init()
	{
		newnode(0),newnode(-1);
		s[n]=-1;
		fail[0]=1;
	}
	int FL(int x)
	{
		while(s[n-len[x]-1]!=s[n])x=fail[x];
		return x;
	}
	void add(char c)
	{
		int num=c-'0';
		c-='0';
		s[++n]=c;
		int cur=FL(last);
		if(!next[cur][c])
		{
			int now=newnode(len[cur]+2);
			fail[now]=next[FL(fail[cur])][c];
			next[cur][c]=now;
			if(cur!=1)
			res[now]=(po[len[cur]+2]*c+c+res[cur]*10)%mod;
			else
			res[now]=c;
			ans=(ans+res[now])%mod; 
		}
		last=next[cur][c];
	}
}P;
char s[maxn];
int main()
{
	scanf("%s",s);
	int len=strlen(s);
	po[1]=1;
	for(int i=2;i<=len;i++)po[i]=(po[i-1]*10)%mod;
	P.init();
	for(int i=0;i<len;i++)
	P.add(s[i]);
	printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/ccsu_cat/article/details/83622879
今日推荐