首页 > 其他分享 >[ABC254Ex] Multiply or Divide by 2

[ABC254Ex] Multiply or Divide by 2

时间:2023-12-08 11:37:29浏览次数:34  
标签:ch Divide ABC254Ex leftarrow int 集合 Multiply mx log

[ABC254Ex] Multiply or Divide by 2

题意:

给定大小为 $ n $ 的集合 $ A $ 和 $ B $,你可以对集合 $ A $ 中的元素 $ a_i $ 进行两种操作,分别为 $ a_i \leftarrow \lfloor \dfrac{a_i}{2} \rfloor $,和 $ a_i \leftarrow a_i \times 2 $。你需要操作集合 $ A $ 直至集合 $ A, B $ 完全相同。求最小操作次数,若无解输出 -1

分析:

考虑每次对 \(A,B\) 的最大值进行操作,记 \(A\) 的最大值为 \(mx_A\),\(B\) 的最大值为 \(mx_B\)。

  • \(mx_A=mx_B\) 直接消掉即可。
  • \(mx_A>mx_B\):直接 $mx_A \leftarrow \lfloor \dfrac{mx_A}{2} \rfloor $。
  • \(mx_A<mx_B\): 此时只能用操作 \(2\),但这样就会破坏性质,只用对 $mx_B \leftarrow \dfrac{mx_B}{2} $ 即可,需要注意的是如果 \(mx_B\) 为奇数,就说明 \(A\) 集合内的元素一直乘 \(2\) 都不可能与 \(mx_B\) 相等,即无解。

这样保证了 \(A,B\) 集合内在操作后都为递减。总操作次数最多为 \(\log V\)。

维护这个过程可以使用优先队列。

总时间复杂度 \(O(n \log n \log V)\)。

代码:

#include<bits/stdc++.h>
#define int long long
#define N 100005
using namespace std;
int read() {
	char ch = getchar(); int x = 0, f = 1;
	while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); }
	while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
	return x * f;
}
void write(int x) {
	if(x < 0) putchar('-'), x = -x;
	if(x > 9) write(x / 10);
	putchar('0' + x % 10);
}
int n, ans;
int a[N], b[N];
priority_queue<int>Q1, Q2;
signed main() {
    n = read();
    for(int i = 1; i <= n; i++) a[i] = read(), Q1.push(a[i]);
    for(int i = 1; i <= n; i++) b[i] = read(), Q2.push(b[i]);
    while(!Q1.empty()) {
    	int x = Q1.top(), y = Q2.top();
    	ans++;
    	if(x == y) Q1.pop(), Q2.pop();
    	else if(x > y) Q1.pop(), Q1.push(x / 2);
    	else if(x < y) {
    		if(y % 2 == 1) {
    			write(-1);
    			return 0;
			}
			Q2.pop();
			Q2.push(y / 2);
		}
	}
	write(ans - n); 
	return 0;
}

标签:ch,Divide,ABC254Ex,leftarrow,int,集合,Multiply,mx,log
From: https://www.cnblogs.com/xcs123/p/17884788.html

相关文章

  • CF1901 C Add, Divide and Floor 题解
    LinkCF1901CAdd,DivideandFloorQuestion给定一个长度为\(n\)的序列,每次操作你需要选择一个整数\(x\),并将所有\(a_i\)替换为\(\lfloor\frac{a_i+x}{2}\rfloor\)。求至少多少次操作后能将所有\(a_i\)变相同若最少次数小于等于\(n\),输出操作次数和每次操作所选......
  • [Codeforces] CF1799B Equalize by Divide
    序列操作(divide.cpp)—CF1799B—1200题目描述给您一个\(a_1,a_2,\dotsa_n\)这样的正整数数组,您可以对它进行多次(可以是零次)这样的操作:选择两个索引\(i,j(1\leqi,j\leqn,i\neqj)\);将\(a_i\)赋值为\(\lceil\frac{a_i}{a_j}\rceil\)。这里的\(\lceilx\rceil\)......
  • 无涯教程-NumPy - multiply()函数
    此函数执行多个串联。importnumpyasnpprintnp.char.multiply('Hello',3)其输出如下-HelloHelloHello参考链接https://www.learnfk.com/numpy/numpy-char-multiply.html......
  • AT_abc254_h [ABC254Ex] Multiply or Divide by 2 题解
    打篇题解巩固一下。题意给你两个集合\(A\)和\(B\),对于任意\(A\)集合中的元素,我们可以进行\(2\)种操作:\(a_i\gets\left\lfloor\frac{a_i}{2}\right\rfloor\)或\(a_i\gets2\timesa_i\)。问最少要多少次才能使\(A\)和\(B\)中的元素相等。分析首先我们可以令\(a......
  • Deltix Round, Autumn 2021 (open for everyone, rated, Div. 1 + Div. 2) A. Divide
    有一个长为\(n\)的数组,可以执行以下整份操作任意次:选择任意两个数\(a_i,a_j\),满足\(2\mida_i\)\(a_i=\frac{a_i}{2}\)\(a_j=2\cdota_j\)请找到经过任意此操作后的最大\(\sum_{i=1}^{n}a_i\)。在唯一分解定理下讨论两个数\(a_i=2^{\alpha_i}\cdotx,a......
  • 【刷题笔记】29. Divide Two Integers
    题目Giventwointegers dividend and divisor,dividetwointegerswithoutusingmultiplication,divisionandmodoperator.Returnthequotientafterdividing dividend by divisor.Theintegerdivisionshouldtruncatetowardzero.Example1:Input:dividen......
  • AGC064C Erase and Divide Game
    题面传送门首先考虑你只插入若干个数怎么做:按位从低到高插入一棵Trie,问题就变成:在Trie上每次可以往左儿子走或者往右儿子走,如果当某个人操作的时候为空节点那么这个人就输了。如果我们可以将这棵树建出来那么这个问题就是好解决的,可惜建不出来。仿照从高到低建Trie的方法,将......
  • maltab 利用不同方式(自编高斯赛德尔迭代函数,逆矩阵,左除(\)运算)求解线性方程组的速度
    参考:matlabhelp文档:mldivide实际测试比较,这里K_Tem为一个2398*2398的稀疏矩阵,Guass_Seidal是自己写的高斯赛德尔迭代函数 ......
  • strDivide2.cpp字符串划分
    //strDivide2.cpp:Definestheentrypointfortheconsoleapplication.//#include"stdafx.h"#include"string.h"/*s为bwe@#$at111YYY*oo那么func(s)将打印atbweooYYY★树★(240028358)21:07:57先挑字母,再排序吧国嵌唐老师(22134670)21:21:25我来说说......
  • 2021百度之星- 复赛 Add or Multiply 1 第二类斯特林数计数
    AddorMultiply1本质上这个题目中乘法和加法没有任何区别因为加法乘法均满足交换律不妨考虑乘法最后分成了k块每块内部没有顺序但是块之间有顺序有顺序共有m个乘法操作这样的方案数是\(s(m,k)k!\)这个时候要求k-1个空隙必须有加法但是开头和结尾可以有也可以没有这个......