社区讨论

萌新刚学oi,这题WA10求助

CF700ECool Slogans参与者 4已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mi7w0c1d
此快照首次捕获于
2025/11/21 04:31
4 个月前
此快照最后确认于
2025/11/21 04:31
4 个月前
查看原帖
思路是后缀自动机上的right集合用线段树合并求得,接着在parent树上树形dp,但是似乎线段树合并写的有点萎,有没有大佬能帮忙康康qwq
代码如下:
CPP
#include<bits/stdc++.h>
#define N 400040
#define lson tr[now].l
#define rson tr[now].r
using namespace std;

int n;
char s[200020];

struct SM
{
	struct point 
	{
		int son[26],len,mx,at,fa;
	}t[N];
	
	struct tree
	{
		int sum,l,r;
	}tr[N<<4];
	
	int last=1,cnt=1,gg=0;
	int tot=0;
	int rt[N];
	int top[N],dp[N];
	bool sz[N],vis[N];
	vector<int> g[N];
	
	void add(int c)
	{
		int p=last;
		int np=++cnt;
		t[np].len=t[p].len+1;
		t[np].at=++gg;
		sz[np]=1;
		while(p&&(!t[p].son[c]))
		{
			t[p].son[c]=np;
			p=t[p].fa;
		}
		if(!p) t[np].fa=1;
		else
		{
			int q=t[p].son[c],nq;
			if(t[q].len==t[p].len+1)
			{
				t[np].fa=q;
			}
			else
			{
				nq=++cnt;
				t[nq]=t[q];
				t[nq].len=t[p].len+1;
				t[np].fa=t[q].fa=nq;
				t[nq].at=t[np].at;
				while(p&&(t[p].son[c]==q))
				{
					t[p].son[c]=nq;
					p=t[p].fa;
				} 
			}
		}
		last=np;
	}

	void push_up(int now)
	{	
		tr[now].sum=tr[lson].sum+tr[rson].sum;
	}
	
	void insert(int &now,int l,int r,int pos,int val)
	{
		if(!now) now=++tot;
		if(l==r) 
		{
			tr[now].sum=val;
			return ;
		}
		int mid=(l+r)>>1;
		if(pos<=mid)
		{
			insert(lson,l,mid,pos,val);
		}
		else
		{
			insert(rson,mid+1,r,pos,val);
		}
		push_up(now);
	}
	
	int query(int now,int l,int r,int ll,int rr)
	{
		if(ll>rr) return 0;
		if(!now) return 0;
		if(ll<=l&&r<=rr)
		{
			return tr[now].sum;
		} 
		int mid=(l+r)>>1;
		if(rr<=mid)
		{
			return query(lson,l,mid,ll,rr);
		}
		else
		{
			if(ll>mid)
			{
				return query(rson,mid+1,r,ll,rr); 
			}
			else
			{
				return query(lson,l,mid,ll,mid)+query(rson,mid+1,r,mid+1,rr);
			}
		}
	} 
	
	int merge(int a,int b,int l,int r)
	{
		if(!a) return b;
		if(!b) return a;
		if(l==r)
		{
			tr[a].sum=tr[b].sum;
			return a;
		}
		int mid=(l+r)>>1;
		tr[a].l=merge(tr[a].l,tr[b].l,l,mid);
		tr[a].r=merge(tr[a].r,tr[b].r,mid+1,r);
		push_up(a);
		return a;
	}
	
	int dfs(int now)
	{
		if(sz[now])
		{
			insert(rt[now],1,n,t[now].at,1);
		}
		for(int i=0;i<g[now].size();i++)
		{
			dfs(g[now][i]);
			merge(rt[now],rt[g[now][i]],1,n);
		}
	}
	
	int dfs1(int now)
	{
		if(query(rt[top[t[now].fa]],1,n,t[now].at-t[now].len+t[top[t[now].fa]].len,t[now].at-1))
		{
			dp[now]=dp[t[now].fa]+1;
			top[now]=now;
		}
		else
		{
			dp[now]=dp[t[now].fa];
			top[now]=top[t[now].fa];
		}
		
		for(int i=0;i<g[now].size();i++)
		{
			dfs1(g[now][i]);
		}
	}
	
	int print(int now,int l,int r)
	{
		if(l==r)
		{
			if(tr[now].sum) printf("%d ",l);
			return 0; 
		}
		int mid=(l+r)>>1;
		if(tr[lson].sum) print(lson,l,mid);
		if(tr[rson].sum) print(rson,mid+1,r);
	}
	
	int solve()
	{
		for(int i=1;i<=cnt;i++)
		{
			g[t[i].fa].push_back(i);
		}
		for(int i=1;i<=cnt;i++)
		{
			rt[i]=i;
			tot++;
		}
		dfs(1); 
		for(int i=0;i<g[1].size();i++)
		{
			top[g[1][i]]=g[1][i];
			dp[g[1][i]]=1;
			for(int j=0;j<g[g[1][i]].size();j++)
			{
				dfs1(g[g[1][i]][j]);
			}
		}
		int ans=0;
		for(int i=1;i<=cnt;i++)
		{
			ans=max(ans,dp[i]);
		}
		printf("%d\n",ans);
	}
}sm;

int main()
{
	scanf("%d",&n);
	scanf("%s",s);
	n=strlen(s);
	for(int i=0;i<n;i++)
	{
		sm.add(s[i]-'a');
	}
	sm.solve();
} 

回复

3 条回复,欢迎继续交流。

正在加载回复...