Codeforces 558C AMR and chemistry all disguised

Source: Internet
Author: User
Tags getbase greatest common divisor



Test instructions: Given a sequence, each operation can only multiply a number by 2 or by 2 (rounded down). The minimum number of operations makes all the numbers the same value.







It didn't come true at the end of the game. Alas, after a drop. Began to think twice, but half a day can not think how to judge. Later found that each number can be turned into a few (up to 400), so think of using mathematical methods + a bit of violence, but time is not enough.

It's not really a number-theoretic question. It just used some math ideas. A bit of preprocessing is required, and the second-point technique is used in the subsequent calculations.

For a certain number of n, set n = S*2^r (where S is an odd number), then n can be turned into something like this: s*2^k (k = 0,1,2 ...). ) and the smaller number that s can become. s can become the number of S/2, set s/2 = S ' *2^r ', can also become S ' *2^k (k = 0,1,2 ...). and S ' can become a smaller number ... Then go on. So we can notice a situation where a number a can become a number n, then a number a must be a number s. Conversely, if a number cannot become a number s, then it must not become a number n. Further, if two number A, a, B, can become n, then both a and a must be able to become S. So, we can first find this s, that is, all the numbers can become S. Note that because S is odd, each number turns to S can only be the result of being divided by 2 (rounded down). And, we can at least find one of these s coming out--s = 1. This is obvious. So in order to make the number of operations less, we take the largest in s (certainly not necessarily optimal). But obviously, all the numbers must be able to turn into this number, that's for sure. In other words, an odd number larger than this will not change. In that case, the number of candidates that can be turned into the last is only S and s*2^k (k = 0,1,2 ...). So we enumerate the values of K, calculate the number of times each number becomes s*2^k, and then add the minimum value to update.

It is somewhat similar to asking for "greatest common divisor" of all numbers. Just here is the biggest odd number that x and Y can change to. It is also used recursively: if x is twice times greater than Y, then x/=2, if Y is twice times larger than X, then y/=2, otherwise x and Y are divided by 2 at the same time, until x and y are equal, that is, the largest odd number that can be changed together.

s solved, the second question is how to quickly find the number of times one count needs to become another. A little bit of technique is used here, which can be directly preprocessed to find the complexity of the near O (1).

First define an array base[i], base[i] satisfies i = base[i]*2^r (in fact Basi[i] is the above-mentioned s), obviously, for the odd have base[i] = i, for even have base[i] = BASE[I/2]. The next step is to calculate the Cal (i, j) = The number of steps required to turn I into J. It can be found that as long as I is divided by 2 until base[i] = Base[j], I and J at this time are only a multiple of the power of 2, then you need to manipulate the power value of the number of times to change I to J. This power value is equal to LOG2 (Max (i,j)/min (i,j)). So we simply need to divide I into a base value equal to Base[j] number of the minimum divided by how many times 2. Of course, the direct calculation can also be divided by 2 until the base value equals Base[j]. But the outer layer has already used the N*log (n) complexity, so here we divide the number of times divided by 2 by 2 points. A maximum of 10W can be divided by 16 times 2. So the complexity of the dichotomy is log2 (16) = 4 is almost equal to O (1). This can be done because, if I divide by 2^k and the base value is smaller than base[j], then dividing by a value greater than 2^k will not get base[i]. Conversely, if I divide by 2^k the base value is larger than base[j], then it will continue to be divided by 2. It is monotonic, so it can be two points. So cal (i,j) = two points out the power value + (int) log2 (max (i, J)/min (I, j));












#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include < cstring> #include <string> #include <stack> #include <queue> #include <vector> #include < map>using namespace Std;const int MAX = 100005;const int INF = Max*20;int base[max];int N, a[max];void Initial ()//pretreatment b        ASE array {for (int i = 1; I <= 100000; i++) {if (i%2) base[i] = i;    else base[i] = BASE[I/2];    }}int getbase (int x, int y)//Recursive two numbers can be changed simultaneously to the largest odd number {if (x = = y) return x;    if (x >> 1 >= y) return getbase (x >> 1, y);    if (x << 1 <= y) return getbase (x, y >> 1); return getbase (x >> 1, y >> 1);}    int cal (int x, int y)//The number of steps required to change x to y {int L = 0, r =, mid;        while (L < r) {mid = (L + r) >> 1;        if (base[x >> mid] > base[y]) L = mid + 1;    else R = Mid;    } x >>= L; Return L + (int) log2 (max (x, y)/min (x, y));} void input () {for (int i = 0; i < n; i++) scanf ("%d", &a[i]);}    void Solve () {int all_base = a[0]; for (int i = 1; i < n; i++) all_base = GetBase (All_base, a[i]);    The largest odd all_base int ans = INF, number = All_base, which all the numbers can become is first calculated;        while (number <= 100000)//enumerates multiples of all_base as last-changed numbers, computes and updates {int sum = 0;        for (int i = 0; i < n; i++) sum + = Cal (A[i], number);        ans = min (ans, sum);    Number <<= 1; } printf ("%d\n", ans);}    int main () {initial ();        while (scanf ("%d", &n)! = EOF) {input ();    Solve (); } return 0;}



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Codeforces 558C AMR and chemistry all disguised

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.