https://codeforces.com/gym/101889/attachments

题意

显然\(\gcd(i,n)\)相等的\(i\),他们的情况完全一致(都可以由多次跳\(\gcd(i,n)\)步转移而来)

那么我们枚举\(n\)的因数,注意是因数而不是质因数

例如对于\(2\)\(4\)

\[ 2:1 \rightarrow 2 \rightarrow 4\\ 4:1 \rightarrow 4 \]

后一种跳过了\(2\),应当分开讨论

先特判\(1\)的情况

然后判断情况是否存在

常规操作,把原串复制一遍

定义\(bool\)类型数组\(dp\)\(dp[i]\)表示跳到\(i\)是否可行

设枚举到因子\(x\)

\[初值:dp[i]=[s[i]='R']\\ 转移:dp[i]=dp[i] \& dp[i-x] \]

\(OK!\)

\(Code:\)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 400005
using namespace std;
int n,ans=0,g=0;
char s[N],w[N];
bool vis[N],dp[N];
void ins(int x)
{
    for (int i=1;i<=(n << 1);i++)
        dp[i]=(w[i]=='R');
    for (int i=x+1;i<=(n << 1);i++)
        dp[i]&=dp[i-x];
    for (int i=n+1;i<=(n << 1);i++)
        if (dp[i])
        {
            vis[x]=true;
            return;
        }
}
int main()
{
    scanf("%s",s);
    n=strlen(s);
    for (int i=0;i<n;i++)
        g+=(int)(s[i]=='P');
    if (!g)
    {
        cout << (n-1) << endl;
        return 0;
    }
    for (int i=1;i<=n;i++)
        w[i]=w[i+n]=s[i-1];
    for (int i=2;i*i<=n;i++)
        if (n%i==0)
        {
            ins(i);
            if (i*i!=n)
                ins(n/i);
        }
    for (int i=1;i<n;i++)
        ans+=(int)vis[__gcd(n,i)];
    cout << ans << endl;
    return 0;
}

相关文章:

  • 2021-11-07
  • 2021-12-19
  • 2021-07-31
  • 2022-12-23
  • 2021-10-11
  • 2021-10-16
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-08-26
  • 2021-10-17
  • 2021-09-20
  • 2021-04-04
  • 2022-12-23
相关资源
相似解决方案