题解:CF1893A Anonymous Informant
主播主播,你的循环节递推确实很强,但还是太吃思维了,有没有什么好想好写的图论建模推荐一下!有的兄弟,有的,像这样的图论建模还有好多,都是现在 CCF 不考的类型,告诉主播你想学哪个!
Sol.1 基环树倍增
注意到把一个序列循环移动后合法的状态只有
发现每个节点最多只有一条出边,是内向基环树森林,于是考虑倍增预处理,然后从状态
时间复杂度
Sol.2 循环节递推
和上面差不多,只是多了个观察:每次移位后的
递推公式:
循环节最多长度为
#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
const int N=200005;
ll n,k,a[N];
bitset<N>vis;
void solve()
{
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
int p=n;
vis.reset();
while(k--)
{
if(a[p]>n)
{
cout<<"No\n";
return;
}
if(vis[p]==1)
{
cout<<"Yes\n";
return;
}
vis[p]=1;
p=(p-a[p]+n-1)%n+1;
}
cout<<"Yes\n";
}
int main()
{
//freopen("sample.in","r",stdin);
//freopen("sample.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)solve();
return 0;
}