在C++中查找单调序列中的元素位置
概念
对于给定的整数l和一个单调递增序列:
f(m) = am + bm [log₂(m)] + cm³ 其中 (a = 1, 2, 3, …), (b = 1, 2, 3, …), (c = 0, 1, 2, 3, …) 注意,[log₂(m)] 表示取以2为底的对数并向下取整。因此,
如果 m = 1,则值为 0。
如果 m = 2-3,则值为 1。
如果 m = 4-7,则值为 2。
如果 m = 8-15,则值为 3。
我们的任务是确定使得 f(m) = l 的值 m,如果 l 不属于该序列,则我们必须打印 0。
需要注意的是,这些值可以用64位表示,三个整数 a、b 和 c 不超过 100。
输入
a = 2, b = 1, c = 1, l = 12168587437017
输出
23001 f(23001) = 12168587437017
输入
a = 7, b = 3, c = 0, l = 119753085330
输出
1234567890
方法
**使用朴素方法** - 对于给定的 a、b、c 值,找到每个 m 值的 f(m) 值并进行比较。
**使用高效方法** - 实现二分查找,选择 m = (min + max) / 2,其中 min 和 max 分别表示 m 的最小值和最大值,然后:
- 如果 f(m) < l,则递增 m。
- 如果 f(m) > l,则递减 m。
- 如果 f(m) = l,则 m 即为所需答案。
- 现在重复上述步骤,直到找到所需的值或该值在序列中不存在。
示例
// C++ implementation of the approach #include <iostream> #include <math.h> #define SMALL_N 1000000 #define LARGE_N 1000000000000000 using namespace std; // Shows function to return the value of f(m) for given values of a, b, c, m long long func(long long a1, long long b1, long long c1, long long m){ long long res1 = a1 * m; long long logVlaue1 = floor(log2(m)); res1 += b1 * m * logVlaue1; res1 += c1 * (m * m * m); return res1; } long long getPositionInSeries1(long long a1, long long b1, long long c1, long long l){ long long start1 = 1, end1 = SMALL_N; // Now if c is 0, then value of m can be in order of 10^15. // Now if c1!=0, then m^3 value has to be in order of 10^18 // so maximum value of m can be 10^6. if (c1 == 0) { end1 = LARGE_N; } long long ans1 = 0; // Now for efficient searching, implement binary search. while (start1 <= end1) { long long mid1 = (start1 + end1) / 2; long long val1 = func(a1, b1, c1, mid1); if (val1 == l) { ans1 = mid1; break; } else if (val1 > l) { end1 = mid1 - 1; } else { start1 = mid1 + 1; } } return ans1; } // Driver code int main(){ long long a1 = 2, b1 = 1, c1 = 1; long long l = 12168587437017; cout << getPositionInSeries1(a1, b1, c1, l)<<endl; long long a2 = 7, b2 = 3, c2 = 0; long long l1 = 119753085330; cout << getPositionInSeries1(a2, b2, c2, l1)<<endl; long long a3 = 6, b3 = 2, c3 = 1; long long l2 = 11975309533; cout << getPositionInSeries1(a3, b3, c3, l2)<<endl; return 0; }
输出
23001 1234567890 0
广告