ZJSU五月多校合训

强度焦虑制造者

具体而言,zszz3在每个游戏版本中都会推出一名新角色,或加强一名旧角色。玩家必须将这名新角色或 被加强的旧角色编入队伍,否则就会落后于版本。

而编队数量是有限的,这意味着玩家可能不得不踢出一名编队中现有的角色。而若被加强的角色恰好在 玩家的编队中,则可以开心游戏,什么都不用做。

你的舅舅是这家游戏公司的员工,他拿到了策划在未来\(n\)个版本的规划,现在你可以决定每个版本被你 踢出队伍的角色,使得总的踢人次数最少。

题解:贪心 + 模拟

  • 我们每次踢出的人是下次加强最迟的人
  • 我们不妨将每个角色被加强的时间段利用队列存放起来
  • 我们维护一个大根堆的集合,每次删除下次加强最迟的角色
  • 注意如果有个被加强的角色在编队中,我们也需要在集合中更新该角色下一次被加强的时间
  • 注意如果集合的大小就是编队中现有角色的多少,如果编队中角色的数量没有到达上限,我们不需要踢出人,只需要更新该角色下一次被加强的时间即可
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 3e5 + 10, M = 4e5 + 10;

int n, k;
int a[N];
queue<int> q[N];
set<pii, greater<pii>> st;
map<int, bool> mp;

void solve()
{
    cin >> n >> k;
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
        mp[a[i]] = false;
        q[a[i]].push(i);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        if (mp[a[i]])
        {
            st.erase(st.lower_bound(mpk(q[a[i]].front(), a[i])));
            q[a[i]].pop();
            if (q[a[i]].size())
                st.insert({q[a[i]].front(), a[i]});
            else
                st.insert({INF, a[i]});
            continue;
        }
        if (st.size() < k)
        {
            mp[a[i]] = true;
            q[a[i]].pop();
            if (q[a[i]].size())
                st.insert({q[a[i]].front(), a[i]});
            else
                st.insert({INF, a[i]});
        }
        else
        {
            q[a[i]].pop();
            int u = st.begin()->second;
            st.erase(st.begin());
            mp[u] = false;
            mp[a[i]] = true;
            if (q[a[i]].size())
                st.insert({q[a[i]].front(), a[i]});
            else
                st.insert({INF, a[i]});
            ans++;
        }
    }
    cout << ans << endl;
}
signed main(void)
{
    Zeoy;
    int T = 1;
    // cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

EASY XOR PROBLEM

LGXXGL想要构造一个\(0到2^n-1\)的排列\(p\),使得\(sum = \sum_{i=1}^{2^n-1}p_i \bigoplus p_{i-1}\)最小,输出\(sum\)\(998244353\)取模的结果

题解:思维

  • 我们不妨先考虑最高位,想要贪心的使得最高位异或后的\(1\)最少
  • 我们可以将最高位有没有1的数分为两组,每组个数为\(2^{n-1}\),这样的话只会产生1个最高位的1,也就是在两个组交界的地方,对答案的贡献为\(2^{n-1}\)
  • 按照这种思想我们考虑倒数第二位,容易发现,我们可以在原先分组的基础上每组之间再分成两组,那么对答案的贡献为\(2^{n-2}\times2=2^{n-1}\)
  • 依次类推,我们发现\(sum = 2^{n-1}\times n\)
  • 利用快速幂得到答案即可
posted @ 2023-05-24 20:19  Zeoy_kkk  阅读(12)  评论(0编辑  收藏  举报