题意 : 给定一个长度为n的数列, 首位相接成一个环, 不断遍历这个环, 若 则删除
,并且i++, 直到所有相邻的数gcd均不为1
//https://codeforces.com/contest/1484/problem/D
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const ll inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-4;
const ll mod = 1e9 + 7;
const ll N = 1e5 + 5;
ll n, a[N], nxt[N], vis[N];//nxt[i]记录i后第一个未被删除的数的下标
//vis[i]记录下标为i的数是否被删除, 若a[i] 没有被删除,则a[i+1]不可能被删除
ll gcd(ll x, ll y)
{
return y ? gcd(y, x % y) : x;
}
void solve()
{
cin >> n;
for (ll i = 1; i <= n; i++)
vis[i] = 0;
for (ll i = 1; i <= n; i++)
cin >> a[i];
queue<ll> q;
a[n + 1] = a[1];
for (ll i = 1; i <= n; i++)
{
if (gcd(a[i], a[i + 1]) == 1)
q.push(i);
nxt[i] = i % n + 1;
}
vector<ll> ans;
while (q.size())
{
ll now = q.front();
q.pop();
if (vis[now])//若下标为now的数被删除,则nxt[now]无需删除, 因为now删除后需i向后移1
continue;
vis[nxt[now]] = 1;
ans.push_back(nxt[now]);
nxt[now] = nxt[nxt[now]];//nxt的转移
if (gcd(a[now], a[nxt[now]]) == 1)若删除后相邻的两个数gcd为1则扔进队列
q.push(now);
}
cout << ans.size() << ' ';
for (auto it : ans)
cout << it << ' ';
cout << '\n';
}
signed main()
{
IOS;
ll t = 1;
cin >> t;
while (t--)
solve();
return 0;
}