【hihoCoder 1457】SAM+拓扑排序

题目在这里

题意就不赘述了。

分析:
设cnt[i]表示状态i共有多少串。
那么sum[i]表示状态i的贡献。
那么答案就是sigma(sum[i])
cnt[i]怎么求呢,建立完SAM后对于每一个状态建立拓扑图。
且若在拓扑图上有状态x到状态y的边。
然后拓扑排序的时候记录cnt[i],具体就是若x->y有边,则cnt[y] += cnt[x]。
则对于当前字符ch,有sum[y] += 10sum[x]+ch*cnt[x]。

于是就做完了。

#include <bits/stdc++.h>
#define sc(n) scanf("%d",&n)
#define pt(n) printf("%d\n",n)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e6+7;
const int mod = 1e9+7;
int n;
string s;
ll sum[maxn<<1],cnt[maxn<<1],ind[maxn<<1],vis[maxn<<1];
struct node
{
	int ch[11];
	int len,fa;
}point[maxn<<2];
int las = 1,tot = 1;
void add(char c)
{
	int p = las;
	int np = las = ++tot;
	point[np].len = point[p].len + 1;
	for(;p && !point[p].ch[c];p=point[p].fa) point[p].ch[c] = np;
	if(!p) point[np].fa = 1;
	else
	{
		int q = point[p].ch[c];
		if(point[q].len==point[p].len+1) point[np].fa = q;
		else
		{
			int nq = ++tot;
			point[nq] = point[q];
			point[nq].len = point[p].len+1;
			point[q].fa = point[np].fa = nq;
			for(;p && point[p].ch[c]==q;p=point[p].fa) point[p].ch[c] = nq;
		}
	}
}
void makedeg()
{
	queue<int> q;
	q.push(1);
	while(!q.empty())
	{
		int x = q.front();
		q.pop();
		for(int j=0;j<10;j++)
		{
			int y = point[x].ch[j];
			if(!y) continue;
			if(!vis[y])
			{
				q.push(y);
				vis[y] = 1;
			}
			ind[y]++;
		}
	}
}
void topsort()
{
	queue<int> q;
	q.push(1);
	cnt[1] = 1;
	while(!q.empty())
	{
		int x = q.front();
		q.pop();
		for(int j=0;j<10;j++)
		{
			int y = point[x].ch[j];
			if(!y) continue;
			ind[y]--;
			if(!ind[y]) q.push(y);
			cnt[y] = (cnt[y]+cnt[x])%mod;
			sum[y] = (sum[y]+10*sum[x]+j*cnt[x])%mod;
		}
	}
}
int main()
{
	sc(n);
	while(n--)
	{
		cin>>s;
		for(int j=0;j<s.size();j++) add(s[j]-'0');
		if(n) add(':'-'0');
	}
	makedeg();
	topsort();
	long long ans = 0;
	for(int i=1;i<=tot;i++) ans = (ans+sum[i])%mod;
	printf("%lld\n",ans%mod);
	return 0;
}
发布了159 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/KIKO_caoyue/article/details/99709071
今日推荐