[CF1483B] Playlist - set

Description

有一个包含 \(n\) 首歌的歌单,第 \(i\) 首歌的风格为 \(a_i\),现在循环播放该歌单(听完最后一首歌后回到第一首歌)。

设当前听完的歌 \(B\) 风格为 \(y\) ,上一首听完的歌 \(A\) 风格为 \(x\)

\(\gcd{(x,y)=1}\) ,则删掉歌 \(B\) ,从原歌单中 \(B\) 的下一首歌 \(C\) 开始听(此时不再考虑 \(A\)\(C\) 风格的 \(\gcd\) 的关系)。

请求出被删掉的歌以及删歌的顺序。 |

Solution

一个元素,如果它的下一个元素和它的 GCD = 1,那么我们把这个元素叫做关键元素

随着删除的过程,关键元素可能会变成非关键元素,但是非关键元素一定不会变成关键元素

我们维护一个关键元素的集合,每次通过 upper_bound 找到下一个关键元素即可

每次删除元素后,可能要将相关的元素从关键元素集合中删除

代码中有些奇怪的东西(链表指针),开始做暴力用的

#include <bits/stdc++.h>
using namespace std;

#define int long long

int xbound(const set<int> &s, int x)
{
    auto tmp = s.upper_bound(x);
    if (tmp == s.end())
        return *s.begin();
    return *tmp;
}

void solve()
{
    struct Node
    {
        int val;
        int id;
        Node *next;
    };
    int n;
    cin >> n;
    vector<Node> nodes(n + 2);
    for (int i = 1; i <= n; i++)
        cin >> nodes[i].val, nodes[i].id = i;
    for (int i = 1; i < n; i++)
        nodes[i].next = &nodes[i + 1];
    nodes[n].next = &nodes[1];

    int cnt = 0;
    vector<int> ans;
    int siz = n;

    set<int> s;

    for (int i = 1; i < n; i++)
        if (__gcd(nodes[i].val, nodes[i + 1].val) == 1)
            s.insert(i);
    if (__gcd(nodes[n].val, nodes[1].val) == 1)
        s.insert(n);

    if (s.size())
    {
        Node *p = &nodes[xbound(s, 0)];
        Node *q = p->next;
        int cnt = 0;
        while (siz >= 1 && cnt <= n)
        {
            if (__gcd(p->val, q->val) == 1)
            {
                p->next = q->next;
                ans.push_back(q->id);
                siz--;
                if (s.find(q->id) != s.end())
                    s.erase(q->id);
                if (s.size() == 0)
                    break;
                p = &nodes[xbound(s, p->id)];
                q = p->next;
                cnt = 0;
            }
            else
            {
                s.erase(p->id);
                p = p->next;
                q = q->next;
                cnt++;
            }
        }
    }

    cout << ans.size() << " ";
    for (auto i : ans)
        cout << i << " ";
    cout << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    int t;
    cin >> t;

    while (t--)
    {
        solve();
    }
}

相关文章:

  • 2022-12-23
  • 2021-11-06
  • 2022-12-23
  • 2022-01-25
  • 2021-10-08
  • 2021-05-22
  • 2021-12-13
猜你喜欢
  • 2021-12-09
  • 2021-08-07
  • 2022-12-23
  • 2022-12-23
  • 2021-12-19
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案