首页 > 其他分享 >二进制变化_cf1+2_C. Divisor Chain

二进制变化_cf1+2_C. Divisor Chain

时间:2024-03-07 23:33:22浏览次数:36  
标签:const Divisor Chain 二进制 ll 因子 ans cf1 define

目录

题目概述

原题参考:C. Divisor Chain
给出一个数x,可以对他做以下的变换

  • 若y是x的除数,x-=y
  • 任意的y不能使用超过两次
    可以证明的是,对于任意的数,都可以在1000次操作内将其变成1,请输出将x变为1的操作次数与过程

思路想法

首先是如果随机除以因子的话,那么肯定会很麻烦,因为求因子麻烦,记录因子的使用次数也麻烦,那么就想如何快速的给出因子,而且最好是不一样的,正常的十进制不好做,思考二进制的转化,由此可以得到触发,二进制的最后一位1以后的数是这个数的因子,因此我们可以将任意一个数转化为2的次方,转化为2的次方之后,出现一个问题,如何将其转化为1?毫无疑问,这是不好做的,但是我们很容易将一个2的次方转化为2,再用2转化为1,然后再来思考是否满足题目的第二个要求,明显,对于任意一个因子,只可能最多使用两次(降为2次方一次,降为1一次);至于1000次操作以内,那更是绰绰有余,题目的范围是1e9,“右移”最多32次,“左移”最多32次

参考代码

#include <bits/stdc++.h>
using namespace std;
#define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define pll pair<long long, long long>
#define pii pair<int, int>
#define vi vector<int>
#define vl vector<long long>
#define ll long long
#define ull unsigned long long
const ll INF = 9187201950435737471;
const int inf = 2139062143;
const ll mod = 1e9 + 7;
const double eps = 1e-6;
const double PI = acos(-1.0);
ll x;
ll lowbit(ll x) {return x&-x;}
void solve() {
    ll cnt = 0;
    vector<ll> ans;
    cin >> x;
    ans.push_back(x);
    while(x-lowbit(x)) {
        x -= lowbit(x);
        ans.push_back(x);
    }
    while(x != 2) {
        x >>= 1;
        ans.push_back(x);
    }
    ans.push_back(1);
    cout << ans.size() << endl;
    for(auto x:ans) cout << x << " ";
    cout << endl;
}
int main() {
#ifdef xrl
    freopen("in.txt", "r", stdin), freopen("out.txt", "w", stdout);
#endif
    FAST_IO;
    int t = 1;
    cin >> t;
    while(t --) solve();
#ifdef xrl
    cout << "Time used = " << (double)(clock() * 1.0 / CLOCKS_PER_SEC) << "s";
#endif
    return 0;
}

做题反思

记录一下,这是第一个10分钟以内昨晚的c题hhh,今天的爽局,对于数字转化的题目,如果十进制想不到好办法,可以转化为二进制思考,二进制的因子很好用

标签:const,Divisor,Chain,二进制,ll,因子,ans,cf1,define
From: https://www.cnblogs.com/notalking569/p/18060041

相关文章

  • 如何在langchain中使用openapi
    如何在langchain中使用openapi获得APIKey在当前文件夹里面建一个名为.env的文件,内容如下OPENAI_API_KEY=sk-xxxhNsNyUaQvHc3JyOPENAI_API_BASE=https://api.fe8.cn/v1使用在自己的项目文件夹下,安装项目依赖的包pipinstallpython-dotenvlangchain-openai新建......
  • CF1353E K-periodic Garland 题解
    分析考虑DP。定义状态函数\(f_i\)表示处理完前\(i\)个字符且第\(i\)个字符为\(1\)时的最小代价。则对于\(i\),有两种情况:\(i\)不是第一个\(1\),则上一个\(1\)的位置必定为\(i-k\)。\(i\)是第一个\(1\),没有上一个\(1\)。得到转移方程:\(f_i=\min(f_{\max(......
  • CF1915G Bicycles 题解
    分析参照去年普及组T4,很显然能发现就是一个暴力最短路。设\(dis_{i,j}\)表示从\(1\)走到\(i\)且能得到的\(s\)最小为\(j\)时的最短路。那么答案就是\(\min\{dis_{n,i}|1\lei\leV\}\)。考虑最短路转移。对于当前的\(dis_{u,j}\),走到\(v\)的代价将会是\(w_{u......
  • 从CF1676H2看逆序对的两种求法
    Problem-1676H2-Codeforces思路原问题可以以直接转化成求\(a_i>=a_j(i<j)\)的数量。归并排序原理很直接,归并排序就是为了减少逆序对的数量,所以直接在操作的时候记录减少的数量即可排序后的数组无逆序对,归并排序的合并操作中,每次后段首元素被作为当前最小值取出时......
  • CF1066E 题解
    Solution首先不难想到计算\(a\)的每一位对答案产生的贡献,然后题目告诉我们\(b\)每次会往右移一位,然后结合样例可以发现:对于\(a\)的第\(i\)位,能与其产生贡献的条件是:\(a_i=1\)且\(b_j=1(i\leqj)\),对答案的贡献不难想出即为\(2^{i-1}\times\sum\limits_{j=i}^{m}b_j......
  • CF1824B1 LuoTianyi and the Floating Islands (Easy Version) 题解
    分析按照\(k\)的奇偶分开考虑。\(k\)为奇数。一个好的节点有且仅有一个在任意两个有人的节点\(i,j\)的路径的交点上的最优位置。若该交点偏移\(1\)步,则必然会使路径长度和\(+1\)。故期望为\(1\)。\(k\)为偶数。任意一个好的节点仍然在任意两个有人的节点\(i,j\)的......
  • CF147B 题解
    Solution一道十分典型的dp题。有三个关键点分别是定义状态、优化和答案的统计。首先定义状态,定义\(f_{i,j,p}\)表示\(i\toj\)号节点,共走了不超过\(p\)条边,且是\(i\toj\)的最长路径。不超过\(p\)条边是为了方便转移,而最长路径如果都为负环,说明需要走更多的边,实......
  • CF1070C Cloud Computing 题解
    分析思路不难想,我们对于第\(i\)个计划的时间,可以分成\(l\)和\(r+1\)两部分。用权值线段树维护,在第\(l\)天的时候就将该计划的内容加入权值线段树中,直到过了该计划的时间,也就是第\(r+1\)天,再将这个计划的内容删除。把每一天需要修改的内容存进vector中,修改完查询权值......
  • CF1899G Unusual Entertainment 题解
    分析一眼树上启发式合并。定义\(x_i\)为节点\(i\)在序列\(p\)中的下标。则问题转化为:对于每组\(l,r,k\),询问以\(k\)为根的子树中是否有一个以上的节点,满足\(l\lex_j\ler\)。使用set存以\(i\)为根的子树中\(x_j\)的有序排列。则对于每个\(k=i\)的询问,去合......
  • CF1895D XOR Construction 题解
    分析对于异或,有性质\(a\oplusb=c,a\oplusc=b,a\oplusa=0\)。则对于\(a_i\oplusa_{i+1}\),其表示的结果就是\(b_{i}\oplusb_{i+2}\)。做一个前缀异或和,就能够得到\(b_1\)与\(b_2,b_3,\dots,b_n\)的异或结果。考虑枚举\(b_1\),因为在有解的情况下\(b_1\op......