首页 > 其他分享 >题解:Codeforces Round 961 (Div. 2) C

题解:Codeforces Round 961 (Div. 2) C

时间:2024-07-26 13:18:47浏览次数:6  
标签:平方 le 961 int 题解 justice test Div array

C. Squaring

time limit per test: 2 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

ikrpprpp found an array \(a\) consisting of integers. He likes justice, so he wants to make \(a\) fair — that is, make it non-decreasing. To do that, he can perform an act of justice on an index \(1 \le i \le n\) of the array, which will replace \(a_i\) with \(a_i ^ 2\) (the element at position \(i\) with its square). For example, if \(a = [2,4,3,3,5,3]\) and ikrpprpp chooses to perform an act of justice on \(i = 4\), \(a\) becomes \([2,4,3,9,5,3]\).

What is the minimum number of acts of justice needed to make the array non-decreasing?

ikrpprpp 发现了一个由整数组成的数组 \(a\) 。他喜欢公平,所以想让 \(a\) 变得公平,也就是让它不递减。为此,他可以对数组中的索引 \(1 \le i \le n\) 进行公正操作,将 \(a_i\) 替换为 \(a_i ^ 2\) (位置 \(i\) 的元素及其平方)。例如,如果 \(a = [2,4,3,3,5,3]\) 和ikrpprpp选择在 \(i = 4\) 上执行正义行动,那么 \(a\) 就会变成 \([2,4,3,9,5,3]\) 。

要使数组不递减,最少需要多少次正义行动?

Input

First line contains an integer \(t\) (\(1 \le t \le 1000\)) — the number of test cases. It is followed by the description of test cases.

For each test case, the first line contains an integer \(n\) — size of the array \(a\). The second line contains \(n\) (\(1 \le n \le 2 \cdot 10 ^5\)) integers \(a_1, a_2,\ldots, a_n\) (\(1 \le a_i \le 10 ^ 6\)).

The sum of \(n\) over all test cases does not exceed \(2 \cdot {10}^5\).

输入

第一行包含一个整数 \(t\) ( \(1 \le t \le 1000\) ) - 测试用例的数量。随后是测试用例的描述。

对于每个测试用例,第一行包含一个整数 \(n\) - 数组的大小 \(a\) 。第二行包含 \(n\) ( \(1 \le n \le 2 \cdot 10 ^5\) ) 个整数 \(a_1, a_2,\ldots, a_n\) ( \(1 \le a_i \le 10 ^ 6\) )。

所有测试用例中 \(n\) 的总和不超过 \(2 \cdot {10}^5\) 。

Output

For each testcase, print an integer — minimum number of acts of justice required to make the array \(a\) non-decreasing. If it is impossible to do that, print \(-1\).

输出

对于每个测试用例,打印一个整数--使数组 \(a\) 不递减所需的最小正义行为数。如果无法做到,则打印 \(-1\) 。

Example
input

7
3
1 2 3
2
3 2
3
3 1 5
4
1 1 2 3
3
4 3 2
9
16 2 4 2 256 2 4 2 8
11
10010 10009 10008 10007 10006 10005 10004 10003 10002 10001 10000

output

0
1
-1
0
3
15
55

Note

In the first test case, there's no need to perform acts of justice. The array is fair on its own!

In the third test case, it can be proven that the array cannot become non-decreasing.

In the fifth test case, ikrpprppp can perform an act of justice on index 3, then an act of justice on index 2, and finally yet another act of justice on index 3. After that, \(a\) will become \([4, 9, 16]\).

题意
对每个数可以选择平方或者不平方,可以操作无数次
使得这个数列不递减

我的题解
因为题目给的数据范围很大
如果平方暴力会爆long long
如果开方会丢失精度
所以我们要标记去记录某个数平方了多少次

从第二个数到最后一个数递推(因为第一个数不用动)
首先比较原数字,有两种情况(假设 \(a\) 在 \(b\) 前面)

  • \(a \gt b\)
    • 那我们就是需要让 \(b\) 不断变成 \(b^2\) 直到 \(b \ge a\) (但是要先把b复制出来,让复制体去平方,不要改变 \(b\) 本身,因为 \(b\) 可能还要和后面的数字比较),记录平方的次数,加上 \(a\) 的平方的次数,就是 \(b\) 真正的平方次数。
  • \(a \le b\)
    • 虽然理论上我们不需要比较,但是因为 \(a\) 实际上可能已经平方过,我们去算真正的 \(a\) 又可能会爆long long,所以我们不能暴力
    • 我们可以计算 \(a\) 需要平方多少次才能实现 \(a \ge b\),然后 \(b\) 实际上需要平方的次数就是 \(a\) 实际上平方的次数减去这个数;如果这个数小于 \(0\),那就只能取 \(0\)。

最后,我们对这些平方次数求和,就是答案了。

我的代码

#include <bits/stdc++.h>
#define int long long

int t,n;
const int N = 2e5 + 1;
int a[N];
int ans[N];
int mem,cnt;

void solve() {
    std::cin >> n;
    for(int i = 0 ; i < n ; i ++) std::cin >> a[i];
    for(int i = 1 ; i < n ; i ++) {
        mem = a[i];
        cnt = 0;
        if(mem < a[i-1]) {
            if(mem == 1) {
                std::cout << -1 << "\n";
                return;
            }
            while(mem < a[i-1]) {
                mem *= mem;
                cnt ++;
            }
        }
        else if(a[i-1] != 1){
            while(mem >= a[i-1]) {
                a[i-1] *= a[i-1];
                cnt --;
            }
            if(a[i-1] != mem) cnt ++;
        }

        ans[i] = std::max(cnt + ans[i-1],(int)0);
    }

    int m = 0;
    for(int i = 0 ; i < n ; i ++) {
        m += ans[i];
    }
    std::cout << m << "\n";
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    std::cin >> t;
    while(t--) solve();
    return 0;
}

标签:平方,le,961,int,题解,justice,test,Div,array
From: https://www.cnblogs.com/jiejiejiang2004/p/18324353

相关文章

  • 魔术上网导致Github push 443 问题解决方法
    问题描述使用“kexue上网”工具后,在IDEA中push代码到github时,报错:Failedtoconnecttogithub.comport443:Operationtimedout。同时,使用浏览器访问github也会出现无法访问,偶尔能访问的情况。解决办法gitconfig--globalhttp.proxyhttp://127.0.0.1:1087git......
  • 【题解】「CSP模拟赛」雨天 rain
    雨天rain考场上打了一个动态开点线段树,但是被卡空间了......
  • 最小循环节——题解
    最小循环节题目链接题意简述我们需要找到一个字符\(s\)的最短的循环节,对循环节的定义为,当一个字符串\(t\)能够通过若干次自己加自己得到字符串\(s\),我们就称\(t\)是\(s\)的一个循环节。思路简述根据题意,字符串\(s\)本身就是自己的一个循环节。所以,当我们找不到更......
  • Codeforces Round 958 (Div. 2)
    A.*900水。B.*900发现可以用操作把一串0缩成一个0,1同理。都缩完之后会变成一个01交替的串。比较0和1的个数即可。C.*1300,贪心猜结论。记\(n\)的二进制下有\(x\)个1,\(k\)即为\(x+1\),可以证明这是最长的。从小到大把每一位1去掉后输出剩下的数即可......
  • 使用React脚手架时npx速度慢的问题解决
    React作为目前最流行的前端框架之一,其开发效率和组件化特性受到了开发者的广泛欢迎。然而在使用React脚手架工具,如create-react-app进行项目初始化时,有时会遇到npx命令执行速度非常慢的问题。本文将探讨这一问题的原因,并提供一些有效的解决方案。问题分析npx是Node.js包管......
  • P9304 「DTOI-5」3-1题解,c++树的遍历例题
    题意给定以n(1≤n≤1......
  • 题解:P10570 [JRKSJ R8] 网球(未成功)
    题目链接博客食用更佳:Myblog。这道题不是很难。提交记录分析:\(A\)每转\(a\)圈,\(B\)就转\(b\)圈,不考虑\(c\)的前提下,可知每个齿轮转了\([a,b]\)个齿,\(A\)有\([a,b]\diva\)个齿,\(B\)有\([a,b]\divb\)个齿,接着扩倍扩到都大于\(c\)。拓展:\[[a,b]=......
  • 题解:P10721 [GESP202406 六级] 计算得分(未成功)
    博客食用更佳:Myblog题目传送门分析:这道题是一个标准的dp。我们可以先预处理多个\(\texttt{abc}\)连成的字符串的最大值,之后可以按最长平台的方法处理。步骤:初值:这题不需要赋值,因为题目保证得分是正的,故初值为\(0\)。状态:\(dp_i\)表示连续\(i\)个\(\texttt{abc......
  • Redis缓存面试问题解析:如何有效管理缓存失效策略?
    在技术面试中,Redis缓存是一个常见的话题。面试官往往会考察候选人对缓存机制的理解以及在实际场景中的应用能力。本文将探讨一个在Redis缓存面试中经常被问到的问题,并深入解析其背后的概念和解决方案。面试问题:如何管理Redis缓存的失效策略?问题描述:在高并发的web应用中,缓存是提......
  • 题解:P10043 [CCPC 2023 北京市赛] 广播
    博客使用更佳:Myblog题目传送门这道题是一个标准的dp了,只不过它要倒序来做。还是分三步。初值:初值想必都知道吧,若要求最小值,就把初值设成无穷大,\(dp_{0,i}\)和\(dp_{i,0}\)都要设成\(i\),\(dp_{0,0}\)一定要赋值成\(0\),这是本人亲自犯过的错误QwQ。状态:\(dp_{i,j}......