A. Anonymous Informant

发布时间 2023-12-21 11:06:24作者: 纯粹的

原题链接

前言

一道精简但是内容丰富的题

一些事实

1.循环左移len位后数组的节点对应原数组的节点,相当于在无限自复制循环的数组中将原来的节点右移len位
2.如果该数组能被定点数组循环左移x位得到,那么该数组最后一个节点的值一定是x
3.不管怎么位移,可能的数组最多只有n种不同的情况(1~n分别作为尾节点),所以可能有重复的情况
4.如果同一个节点在尾节点出现两次,说明有循环,循环内的的所有数组都是定点数组

细节

1.当k>n时,我们让k=n因为如果n次循环后的数组仍是定点数组,那么说明事实4成立

代码

#include<bits/stdc++.h>
using namespace std;
int a[200005]={0};
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        cin>>n>>k;
        k=min(k,n);
        for(int i=1;i<=n;i++)cin>>a[i];
        int last=n,flag=1,cf=n;
        do
        {
            if(a[last]>n)
            {
                flag=0;
                break;
            }
            last=(last-a[last]+n-1)%n+1;
        }while((--k)&&last!=cf);
        flag==1?puts("Yes"):puts("No");
    }
    return 0;
}