本文共 1550 字,大约阅读时间需要 5 分钟。
针对给定的数组Arr[n],我们需要计算满足Condition:multipul[L...R]/sum[L...R]==k的区间个数。这种问题可以通过划分区间和利用跳跃指针的技术进行高效求解。
对于数组中某个位置i,当a[i]==1时,它对区间内的乘法操作没有影响,只会影响区间的起始和终止位置。因此,可以跳过这种情况的处理,仅仅考虑实际影响区间乘积的元素。
对于a[i]!=1的情况,我们需要考虑连续区间内的乘积及区间和。为了高效定位满足条件的区间,我们可以利用跳跃指针(Jump pointer)技术。每次跳跃指针的次数不超过60次(这是由于乘数不超过2e18,每次乘以2需要60次以覆盖所有可能情况),这样整体复杂度为O(60n),确保算法在时间上是可行的。
#includeusing namespace std;typedef long long ll;const int N = 2e5 + 5;ll a[N], sum[N], jump[N];ll ans = 0;int main() { ios::sync_with_stdio(false); cin.tie(0); ll n, k; cin >> n >> k; for (int i = 1; i <= n; ++i) { cin >> a[i]; } for (int i = 1; i <= n; ++i) { sum[i] = sum[i-1] + a[i]; } jump[n] = n; jump[n+1] = n+1; for (int i = n-1; i >= 1; --i) { if (a[i] == 1) { jump[i] = jump[i+1]; } else { jump[i] = i; } } for (int i = 1; i <= n; ++i) { ll mul = 1; int last = i; int j = i; while (j <= n && (ll)2e18 / a[j] >= mul) { mul *= a[j]; ll presum = sum[j] - sum[i-1]; if (j == i && mul / presum == k) { ans++; } last = j; j = jump[j+1]; if (mul % k == 0 && (mul / k >= presum && mul / k <= presum + j - last - 1)) { ans++; } } } cout << ans;}
代码主要包含以下几个部分:
转载地址:http://oykiz.baihongyu.com/