CF Round#709 D - Playlist
D - Playlist
思维
st[i] : 第 i 个数是否被删去了
ne[i] : 第 i 个数的下一个数是哪个
del:当前的可能被删掉的数的集合
降复杂度的关键:只有在newdel里的才可能被删去,因为别的数对已经在上一轮被判过了
复杂度为 \(O(nlogn)\)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int a[N], ne[N];
bool st[N];
int n;
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
cin >> T;
while(T--)
{
int n;
cin >> n;
vector<int> del;
for (int i = 0; i < n; i++)
{
cin >> a[i];
st[i] = false;
ne[i] = (i + 1) % n;
del.push_back(i);
}
vector<int> ans;
while(del.size())
{
vector<int> newdel;
for (auto it : del)
{
if (st[it])
continue;
if (gcd(a[it], a[ne[it]]) == 1)
{
ans.push_back(ne[it]);
st[ne[it]] = true;
ne[it] = ne[ne[it]];
//只有在newdel里的才可能被删去,因为别的数对已经在上一轮被判过了
newdel.push_back(it);
}
}
del = newdel;
}
cout << ans.size() << " ";
for (int it : ans)
cout << it + 1 << " ";
cout << endl;
}
return 0;
}