题目链接:https://atcoder.jp/contests/abc161/tasks/abc161_e
题意:给你一个包含 n n n个字符的字符串,其中’o’表示这一天可以上班,'x’表示这一天不能上班。 T a k a h a s h i Takahashi Takahashi想要在这 n n n天里挑 k k k天上班,并且 T a k a h a s h i Takahashi Takahashi在工作一天之后要连续休息 c c c天,问哪几天 T a k a h a s h i Takahashi Takahashi必须工作。
思路:首先我们可以想到我们可以用
b
f
s
bfs
bfs将所有的情况的搜索一遍,但是…
所以我们就可以用一个数组
L
[
]
L[]
L[]来记录
T
a
k
a
h
a
s
h
i
Takahashi
Takahashi在第
i
i
i次工作时最开始的那一天。那么
L
[
i
]
−
>
L
[
i
−
1
]
L[i]->L[i-1]
L[i]−>L[i−1]这么多天内所有为’o’的天都可以是
T
a
k
a
h
a
s
h
i
Takahashi
Takahashi第
i
i
i次工作的那一天。
之后我们可以再用一个数组
R
[
]
R[]
R[]来倒叙的记录
T
a
k
a
h
a
s
h
i
Takahashi
Takahashi在第
i
i
i次工作时最开始的那一天。那么如果
L
[
i
]
=
=
R
[
k
−
i
+
1
]
L[i] == R[k-i+1]
L[i]==R[k−i+1]的话
L
[
i
]
L[i]
L[i]这一天就是
T
a
k
a
h
a
s
h
i
Takahashi
Takahashi必须工作的那一天,是不是很巧妙!!!
AC代码如下:
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define pii pair<int,int>
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define rep(i,a,b) for(int i = (a) ; i <= (b) ; i++)
#define per(i,a,b) for(int i = (a) ; i >= (b) ; i--)
#define mem(a) memset(a,0,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define fast_io ios::sync_with_stdio(false)
const int INF = 1e9;
const LL mod = 1e9 + 7;
const int maxn = 1e7 + 7;
LL ans,n;
map<LL,int>mp;
void check(LL x) {
if(x == 1) return ;
LL m = n;
while(m % x == 0) m /= x;
m %= x;
if(m == 1) {
if(!mp[x]) {
ans++;
mp[x] = 1;
}
}
}
int main() {
while(~slld(n)) {
mp.clear();
ans = 0;
for(LL i = 1; i * i <= n; i++) {
if(n % i == 0) {
check(i), check(n/i);
}
}
for(LL i = 1; i * i <= n - 1; i++) {
if((n-1) % i == 0) {
check(i),check((n-1)/i);
}
}
plld(ans);
}
return 0;
}