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;
}

posted @ 2022-05-23 21:14  hzy0227  阅读(13)  评论(0编辑  收藏  举报