题目大意
给出一个长度为
n
n
n的数组
a
0
,
a
1
,
⋯
,
a
n
−
1
a_0,a_1,\cdots,a_{n-1}
a0,a1,⋯,an−1
进行无限次的变化,
一个数
k
k
k,在一次变化后它变为
k
+
a
k
%
n
k+a_{k \% n}
k+ak%n。
会不会在某次变化后,两个原本不相同的数变成了同一个数?
时间限制
1s
数据范围
n
≤
2
×
1
0
5
n\le2\times 10^5
n≤2×105
−
1
0
9
≤
a
i
≤
1
0
9
-10^9\le a_i \le 10^9
−109≤ai≤109
题解
虽然变化次数和参与变化的数是无穷无尽的,
其实不难发现只需要关系
[
0
,
n
)
[0,n)
[0,n)就好了,而且只需要关注一次变化即可。
n
n
n不算太大,只需要拿个数据记录一下就可以了。
Code
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#define G getchar
#define ll long long
using namespace std;
int read()
{
char ch;
for(ch = G();(ch < '0' || ch > '9') && ch != '-';ch = G());
int n = 0 , w;
if (ch == '-')
{
w = -1;
ch = G();
} else w = 1;
for(;'0' <= ch && ch <= '9';ch = G())n = (n<<1)+(n<<3)+ch-48;
return n * w;
}
const int N = 200003;
int n , a[N] , tmp;
bool ans;
set<int> q;
int main()
{
//freopen("1.txt","r",stdin);
//freopen("2.txt","w",stdout);
for (int T = read() ; T ; T--)
{
n = read();
q.clear();
for (int i = 0 ; i < n ; i++)
a[i] = read();
ans = 1;
for (int i = 0 ; i < n ; i++)
{
tmp = i + a[i];
tmp = tmp % n;
if (tmp < 0) tmp = tmp + n;
if (q.count(tmp))
{
ans = 0;
break;
}
q.insert(tmp);
}
if (ans) puts("YES"); else puts("NO");
}
return 0;
}