[NOI2014] 动物园

  • 似乎有O(n)的做法,但我想到的是用树状数组维护
  • 注意树状数组维护的值域范围为1~n,(如果需要维护)0要特判
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int ne[1000005],c[1000005],num[1000005];
vector<int>a[1000005];
string s;
int lowbit(int n)
{
	return n&(-n);
}
void add(int n,int v)
{
	if(n==0)
	{
		return;
	}
	while(n<=s.size())
	{
		c[n]+=v;
		n+=lowbit(n);
	}
}
int ask(int n)
{
	int s=0;
	while(n>0)
	{
		s+=c[n];
		n-=lowbit(n);
	}
	return s;
}
void dfs(int n1)
{
	num[n1]=ask(n1/2);
	add(n1,1);
	for(int i=0;i<a[n1].size();i++)
	{
		dfs(a[n1][i]);
	}
	add(n1,-1);
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>s;
		for(int i=0;i<=s.size();i++)
		{
			a[i].clear();
		}
		ne[1]=0;
		a[0].push_back(1);
		for(int i=2;i<=s.size();i++)
		{
			int j=ne[i-1];
			while(j!=0&&s[j]!=s[i-1])
			{
				j=ne[j];
			}
			if(s[j]==s[i-1])
			{
				j++;
			}
			ne[i]=j;
			a[j].push_back(i);
		}
		dfs(0);
		long long ans=1;
		for(int i=1;i<=s.size();i++)
		{
			ans=ans*(num[i]+1)%mod;
		}
		printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2024-01-30 15:02  D06  阅读(2)  评论(0编辑  收藏  举报