码迷,mamicode.com
首页 > 其他好文 > 详细

[CF1469D] Ceil Divisions - 构造

时间:2021-02-16 12:08:36      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:c++   span   停止   code   math   desc   i++   visio   back   

[CF1469D] Ceil Divisions - 构造

Description

给定一个长度为 n 的序列 ai=i,每次可以选择两个数 x,y,将 ax 改为 ceil(ax/ay),在 n+5 步操作内将 a 修改为 n-1 个 1 和 1 个 2 构成的序列。

Solution

如果是 n+25,我们显然会考虑先用 i 除以 n 做到 1,1,1,...,2,n 的情况,然后不断除即可

现在要求 n+5,我们考虑一下根号,在找到第一个小于 sqrt(n) 的数的时候,把当前的最大值 n 做掉(用 n 除以 sqrt(n)),更新集合然后继续

具体地,我们用一个 set 维护,每次取出当前最大值 y 和次大值 x,如果 \(x^2 > y\),那么直接将次大值做成 1 了,删掉就好;否则,用次大值去除最大值,除出来的元素塞回去

执行到 y=2,x=1 时停止

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

#define int long long
const int N = 200005;

int t, n, a[N];

signed main()
{
    ios::sync_with_stdio(false);

    cin >> t;
    while (t--)
    {
        cin >> n;
        multiset<pair<int, int>> s;
        for (int i = 1; i <= n; i++)
            s.insert({i, i});
        vector<pair<int, int>> ans;
        while (true)
        {
            pair<int, int> y = *s.rbegin(), x = *(++s.rbegin()), z = *(++(++s.rbegin()));
            // cerr << x.first << " " << y.first << endl;
            if (y.first == 2 && x.first == 1)
                break;
            if (x.first * x.first > y.first && z.first != 1)
            {
                ans.push_back({x.second, y.second});
                s.erase(x);
                x.first = 1;
                s.insert(x);
            }
            else
            {
                ans.push_back({y.second, x.second});
                s.erase(y);
                y.first = (y.first + x.first - 1) / x.first;
                s.insert(y);
            }
        }
        cout << ans.size() << endl;
        for (auto [x, y] : ans)
            cout << x << " " << y << endl;
    }
}

[CF1469D] Ceil Divisions - 构造

标签:c++   span   停止   code   math   desc   i++   visio   back   

原文地址:https://www.cnblogs.com/mollnn/p/14398999.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!