zoukankan      html  css  js  c++  java
  • [CF1483B] Playlist

    [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();
        }
    }
    
  • 相关阅读:
    careercup-高等难度 18.1
    面试——网络
    堆和栈的区别(转过无数次的文章)
    Linux用户空间与内核空间(理解高端内存)
    Linux内存管理
    位操作实现加减乘除四则运算
    栈的压入和弹出序列
    DG gap sequence修复一例
    ORACLE 11gR2 DG(Physical Standby)日常维护02
    oracle的特殊权限s bit丢失
  • 原文地址:https://www.cnblogs.com/mollnn/p/14565232.html
Copyright © 2011-2022 走看看