2020 년 문자열 특별 훈련 경기 01

먼저 중점 문제 G 문제: 반성: 1. G 문 제 를 풀 지 못 한 직접적인 원인 은 문 제 를 이해 하지 못 한 것 이다. 2. hash 로 풀 려 고 했 지만 성공 하지 못 했다. / / 내 가 너무 못 했다.
       : s  m                  
           :    
                        
       :1.     ,  ,          ,       0.
                      2.       ,            
               
                         ,    hash ,             next  
                          (  k)    k length-(a[i]-a[i-1])   k     
#include
using namespace std;
int next1[1000];
int a[1000];
int n,m;string s;
void nt()
{
	int i=0;
	int j=-1;
	next1[0]=-1;
	while(i<s.size())
	{
		if(j==-1||s[i]==s[j])
		{
		next1[++i]=++j;
		}
		else
		j=next1[j];
			}
	 
} 

 int main()
 {
 	int n,m;
 	cin>>n>>m;
 	int sum=0;
 	cin>>s;
 	int k=s.size();
 	nt();
 	for(int i=0;i<m;i++)
 	{
 		cin>>a[i];
	 }	
	// cout<
	for(int i=1;i<n;i++)
	{
		if(a[i]-a[i-1]>=k)
		{
			sum+=a[i]-a[i-1]-k;
		}
		else
		{
			if(a[i]-a[i-1]!=k-next1[k])
			return 0;
			else
			continue;
		}
	}
 	
 }

이것 이 바로 이 문 제 를 처리 한 후의 코드 입 니 다. 그리고 해 야 할 일 은 당신 이 가지 고 있 는 26 ^ sum 의 차방 을 계산 하 는 것 입 니 다. 이것 은 바로 빠 른 속도 로 알고리즘 을 사용 하 는 것 입 니 다. / 이상 의 코드 를 long 으로 바 꾸 는 것 을 기억 하 세 요.
#include
using namespace std;
long long next1[1000010];
long long a[1000010];
long long n,m;string s;
long long mod=1e9+7;
void nt()
{
	long long i=0;
	long long j=-1;
	next1[0]=-1;
	while(i<s.size())
	{
		if(j==-1||s[i]==s[j])
		{
		next1[++i]=++j;
		}
		else
		j=next1[j];
			}
	 
} 
long long quick(long a,long b)
{
    long long ans=1;
    while(b)
    {
        if(b&1) ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans%mod;
}

 int main()
 {
 	long long n,m;
 	cin>>n>>m;
 		long long cnt;
 	long long sum=0;
 	cin>>s;
 	long long k=s.size();
 	if(m==0)
 	{
 	cnt=quick(26,n);
 	cout<<cnt<<endl;
 	return 0;
	 }
 	nt();
 	for(long long i=0;i<m;i++)
 	{
 		cin>>a[i];
	 }	
	// cout<
	for(long long i=1;i<m;i++)
	{
		if(a[i]-a[i-1]>=k)
		{
			sum+=a[i]-a[i-1]-k;
		}
		else
		{
			if(a[i]-a[i-1]!=k-next1[k])
			{
				
				cout<<0<<endl;
				return 0;
			}
			else
			continue;
		}
		
	}
	
	if(a[m-1]+k-1>n)
	{
	
		cout<<"0"<<endl;
		return 0;
	}
	else
	sum+=n-(a[m-1]+k-1);
 cnt=quick(26,sum);
 	cout<<cnt<<endl;
 }
 

ok 여기까지 왔 습 니 다. 모든 문 제 는 기본적으로 해결 되 었 습 니 다.그리고 이렇게 하루 걸 렸 어 요...곰 곰 이 생각해 보 니 문 제 는 구간 에서 중복 되 는 문제 에서 비롯 되 었 다. 예 를 들 어 ababab 라 는 예 는 가장 긴 절 이 4 차장 이 2 인 다음 에 내 가 쓴 방식 인 a[i]-a[i-1]!=k-next1[k] 으로 대응 하 는 위치 인지 아 닌 지 를 판단 하 는 것 이 잘못 되 었 다. 데이터 가 잘 만 들 어 졌 다 면 이것 은 우연성 이 있다 는 것 을 알 게 될 것 이다.똑 같 아 도 순환 절 위치 가 똑 같 지 는 않 을 거 라 고 생각 했 습 니 다.다시 많은 대신 들 의 해법 을 본 후에 나 는 bool 유형의 배열 을 사용 하여 모든 순환 절 을 표시 할 수 있다 는 것 을 알 게 되 었 다. 표 시 를 한 후에 그들 이 겹 치 는 위치 가 순환 절 인지 아 닌 지 를 판단 하면 된다 는 것 을 알 게 될 것 이다.따라서 next 배열 을 변경 하고 visited 배열 이 visited 에 대한 표 시 를 추가 해 야 합 니 다. 다음 코드 를 사용 할 수 있 습 니 다.
for(int i=s.size()-1;i;i=next1[i])
			visited[i]=true;
			

이렇게 하면 모든 순환 절 을 표시 할 수 있 기 때문에 우리 가 일치 할 때 강 강 은 그 가 표시 되 었 는 지 없 는 지 를 표시 하면 된다.
#include
using namespace std;
long long next1[1000100];
long long a[1000100];
long long n,m;string s;
long long mod=1e9+7;
bool visited[1000100];
void nt()
{
	long long i=0;
	long long j=-1;
	next1[0]=-1;
	while(i<s.size())
	{
		if(j==-1||s[i]==s[j])
		{
		next1[++i]=++j;
		}
		else
		j=next1[j];
			}
			for(int i=s.size()-1;i;i=next1[i])
			{
				visited[i]=true;
			//	cout<
			}
	 
} 
long long quick(long a,long b)
{
    long long ans=1;
    while(b)
    {
        if(b&1) ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans%mod;
}

 int main()
 {
 	long long n,m;
 	cin>>n>>m;
 		long long cnt;
 	long long sum=0;
 	cin>>s;
 	long long k=s.size();
 	if(m==0)
 	{
 	cnt=quick(26,n);
 	cout<<cnt<<endl;
 	return 0;
	 }
 	nt();
 	for(long long i=0;i<m;i++)
 	{
 		cin>>a[i];
	 }	
	// cout<
	for(long long i=1;i<m;i++)
	{
		if(a[i]-a[i-1]>=k)
		{
			sum+=a[i]-a[i-1]-k;
		}
		else
		{
			if(!visited[a[i-1]+k-a[i]])
			{
				
				cout<<0<<endl;
				return 0;
			}
			else
			continue;
		}
		
	}
	
	if(a[m-1]+k-1>n)
	{
	
	cout<<"0"<<endl;
		return 0;
	}
	else
	sum+=n-(a[m-1]+k-1);
	sum+=a[0]-1;
 cnt=quick(26,sum);
 	cout<<cnt<<endl;
 }

주의해 야 할 상황 은 1. m = = 0. 2. 첫 번 째 값 이 꼭 1 부터 시작 되 는 것 은 아 닙 니 다... /어쨌든 나 는 구덩이 가 있 으 면 반드시 뛰 고, 마음 이 피곤 하 다.이 문제 의 방법 중 하 나 는 문자열 hash 방법 입 니 다.
https://blog.csdn.net/Binary_Heap/article/details/81983606?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
이것 은 큰 신 이 쓴 것 이 니 참고 할 수 있다.

좋은 웹페이지 즐겨찾기