【学习笔记】[AGC033E] Go around a Circle
不妨假设 
     
      
       
        
        
          S 
         
        
          0 
         
        
       
         = 
        
       
         R 
        
       
      
        S_0=R 
       
      
    S0=R,做出如下观察:
  
     
      
       
       
         1.1 
        
       
      
        1.1 
       
      
    1.1 不存在 
     
      
       
       
         B 
        
       
      
        B 
       
      
    B的连续段
  
     
      
       
       
         1.2 
        
       
      
        1.2 
       
      
    1.2 不存在长度为偶数的 
     
      
       
       
         R 
        
       
      
        R 
       
      
    R的连续段
  
     
      
       
       
         1.3 
        
       
      
        1.3 
       
      
    1.3 对于 
     
      
       
        
        
          S 
         
        
          i 
         
        
       
         = 
        
       
         L 
        
       
      
        S_i=L 
       
      
    Si=L的情况,事实上这个棋子的移动方向是确定的,取决于上一段 
     
      
       
       
         R 
        
       
      
        R 
       
      
    R的奇偶性
  
     
      
       
       
         1.4 
        
       
      
        1.4 
       
      
    1.4 设 
     
      
       
       
         S 
        
       
      
        S 
       
      
    S中连续的 
     
      
       
       
         R 
        
       
      
        R 
       
      
    R最短为 
     
      
       
       
         Y 
        
       
      
        Y 
       
      
    Y,如果圆上任意圆弧的长度 
     
      
       
       
         ≤ 
        
       
         Y 
        
       
      
        \le Y 
       
      
    ≤Y,那么可以从圆弧一端走到另一端,因此一定合法。能否证明这是充要的呢?取最长一段圆弧和最短一段 
     
      
       
       
         R 
        
       
      
        R 
       
      
    R,从圆弧的两端出发逆序操作就能找到出发点。因为圆弧两端奇偶性不同,因此必然存在一个点跨过了整段圆弧,证毕。 注意,我们只考虑长度为奇数的连续的 
     
      
       
       
         R 
        
       
      
        R 
       
      
    R。
  
     
      
       
       
         1.5 
        
       
      
        1.5 
       
      
    1.5对于 
     
      
       
       
         S 
        
       
      
        S 
       
      
    S中长度为偶数的连续的 
     
      
       
       
         R 
        
       
      
        R 
       
      
    R,发现可以缩掉,这样会出现连续的 
     
      
       
       
         B 
        
       
      
        B 
       
      
    B,那么只要不是出现在开头,这些 
     
      
       
       
         B 
        
       
      
        B 
       
      
    B都没有影响,因此如果开头的 
     
      
       
       
         R 
        
       
      
        R 
       
      
    R是奇数,那么不用考虑,如果是偶数,设长度为 
     
      
       
       
         Z 
        
       
      
        Z 
       
      
    Z,那么圆弧长度不能超过 
     
      
       
       
         Z 
        
       
         + 
        
       
         1 
        
       
      
        Z+1 
       
      
    Z+1,据此对 
     
      
       
       
         Y 
        
       
      
        Y 
       
      
    Y修正即可。
大力 d p dp dp即可。复杂度 O ( n ) O(n) O(n)。
似乎细节比较多
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int mod=1e9+7;
int n,m,a[200005],L(inf);
ll dp[200005][2],f[200005],res;
string s;
ll ask(int i,int j){
	return i<=0?0:dp[i][j];
}
signed main(){
	cin>>n>>m>>s;for(int i=0;i<m;i++)a[i+1]=(s[i]=='R');
	if(!a[1])for(int i=1;i<=m;i++)a[i]^=1;
	int j=1;
	for(int i=1;i<=m;i++){
		if(!a[i]){
			if((i-j)&1)L=min(L,i-j);
			else if(j==1)L=min(L,i);
			j=i+1;
		}
	}if(L==inf){
		f[1]=1;res=n+1;
		for(int i=2;i<n;i++){
			ll x=f[i-2];
			f[i]=(f[i-1]+x)%mod;
			res=(res+(n-i+1)*x)%mod;
		}cout<<res<<"\n";
		return 0;
	}
	dp[1][1]=1;if(L>=n-1&&(n-1&1))res=n;
	for(int i=2;i<n;i++){
		ll x=ask(i-1,i&1)-ask(i-L-2,i&1);
		dp[i][i&1]=(dp[i-1][i&1]+x)%mod;
		dp[i][!(i&1)]=dp[i-1][!(i&1)];
		if(n-i<=L&&(n-i&1))res=(res+(n-i+1)*x)%mod;
	}
	cout<<(res+mod)%mod;
}

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号