萌新刚学SAM 30min求调
查看原帖
萌新刚学SAM 30min求调
956129
z_z_b_楼主2024/12/26 15:36

rt,ty。

#include<bits/stdc++.h>
#define int long long
using namespace std;

namespace io
{
	inline int read(){int x=0,w=0;char c=0;while(!isdigit(c))w|=c=='-',c=getchar();while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();return w?-x:x;}
	template<typename T>inline void write(T x){if(x<0)putchar('-'),x=-x;if(x>9)write(x/10);putchar(x%10+'0');}
	template<typename T>inline void write_(T x){write(x),putchar(' ');}
	template<typename T>inline void writeln(T x){write(x),putchar('\n');}
}
using namespace io;

const int N=1e5+10;
int n,dp[N];char s[N];
struct SAM
{
	struct node{int len,link;map<int,int> ch;}sam[N<<1];
	int sz,last;//注意在主函数初始化 sam[0].link=-1 
	void extend(int c)
	{
		int cur=++sz,p=last;
		sam[cur].len=sam[last].len+1;
		while(p!=-1&&!sam[p].ch.count(c)) sam[p].ch[c]=cur,p=sam[p].link;
		if(p==-1) sam[cur].link=0;
		else
		{
			int q=sam[p].ch[c];
			if(sam[q].len==sam[p].len+1) sam[cur].link=q;
			else
			{
				int copy=++sz;
				sam[copy].len=sam[p].len+1;
				sam[copy].link=sam[q].link;
				sam[copy].ch=sam[q].ch;
				while(p!=-1&&sam[p].ch.count(c))
				{
					if(sam[p].ch[c]==q) sam[p].ch[c]=copy,p=sam[p].link;\
					else break;
				}
				sam[q].link=sam[cur].link=copy;
			}
		}
		last=cur;
	}
}tr;

int dfs(int x)
{
	if(dp[x]) return dp[x];
	for(auto i:tr.sam[x].ch) dp[x]+=dfs(i.second)+1;
	return dp[x];
}

signed main()
{
	n=read();
	scanf("%s",s+1);
	tr.sam[0].link=-1;
	for(int i=1;i<=n;i++) tr.extend(s[i]);
	writeln(dfs(1));
	return 0;
}
2024/12/26 15:36
加载中...