9.6 前缀和
lc
lc504
七进制
reverse
class Solution {
public:
string convertToBase7(int num)
{
string ret;
int temp = num;
if (num < 0) {
num = -num;
}
if (num == 0) {
return "0";
}
while (num)
{
int n = num % 7;
char c = n + '0';
ret += c;
num /= 7;
}
if (temp < 0) {
ret += "-";
}
reverse(ret.begin(), ret.end());
return ret;
}
};
lc3495 前缀和
每个数/4的ops==二进制右移两位
前缀和 f(n) 计算从1到n的每个数所需操作次数之和
再用其差值计算每个查询区间[q[0], q[1]]的操作次数和(f(r)-f(l-1)+1)并取半
最终累加所有查询结果得到总操作次数
class Solution {
public:
long long minOperations(vector<vector<int>>& queries) {
// 计算 [1, x] 的操作次数之和
auto calc = [&](long long x) {
long long ret = 0;
long long p = 1;
// [p, 4p) 范围内的元素,操作次数均为 i
for (int i = 1; p <= x; i++, p *= 4) {
long long cnt = min(p * 4 - 1, x) - p + 1;
ret += cnt * i;
}
return ret;
};
long long ans = 0;
for (auto &qry : queries) {
int l = qry[0], r = qry[1];
ans += max(
// 用前缀和算出 [l, r] 操作次数之和 s,这里求的是 ceil(s / 2)
(calc(r) - calc(l - 1) + 1) / 2,
// 用前缀和算出 r 的操作次数,因为元素越大,操作次数最大
calc(r) - calc(r - 1)
);
}
return ans;
}
};