您的位置:首页 > 其它

Codeforces Round #400 (Div. 1 + Div. 2, combined) C. Molly's Chemicals 区间和、构造、前缀的后缀

2017-03-22 01:11 369 查看
C. Molly's Chemicals

time limit per test
2.5 seconds

memory limit per test
512 megabytes

input
standard input

output
standard output

Molly Hooper has n different kinds of chemicals arranged in a line. Each of the chemicals has an affection value, The i-th
of them has affection value ai.

Molly wants Sherlock to fall in love with her. She intends to do this by mixing a contiguous segment of chemicals together to make a love potion with total affection value as a non-negative integer power
of k. Total affection value of a continuous segment of chemicals is the sum of affection values of each chemical in that segment.

Help her to do so in finding the total number of such segments.

Input

The first line of input contains two integers, n and k,
the number of chemicals and the number, such that the total affection value is a non-negative power of this number k. (1 ≤ n ≤ 105, 1 ≤ |k| ≤ 10).

Next line contains n integers a1, a2, ..., an ( - 109 ≤ ai ≤ 109) —
affection values of chemicals.

Output

Output a single integer — the number of valid segments.

Examples

input
4 2
2 2 2 2


output
8


input
4 -3
3 -6 -3 12


output
3


Note

Do keep in mind that k0 = 1.

In the first sample, Molly can get following different affection values:

2: segments [1, 1], [2, 2], [3, 3], [4, 4];

4: segments [1, 2], [2, 3], [3, 4];

6: segments [1, 3], [2, 4];

8: segments [1, 4].

Out of these, 2, 4 and 8 are
powers of k = 2. Therefore, the answer is 8.

In the second sample, Molly can choose segments [1, 2], [3, 3], [3, 4].

Source

ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined)

My Solution

题意:给出n个数字,要求选出一段连续的数字,使它的和为k的非负整数次方,为这样的区间有多少个。

区间和、构造、前缀的后缀

这是一个很有趣的构造题,一个连续区间[a, b],转化为 [1, b] - [1,a-1],如果差值,满足要求则这样的区间存在,

然后换过来,对于每个k^j,对于 [1,b] - k^j == [1,ax-1],有多少个前缀和sum{[1,ax-1]}就有多少个多少个区间[ax, b] == k^j次。

这里可以借助map来记录 前缀和sum{[1,ax-1]} 出现的次数。

此外要处理2种特殊的情况,一种是k == -1,这时pow_k[j] 只对 -1和1进行讨论, 还有一种是 k == 1,这时pow_k[j]只对 1 进行讨论。

从而巧妙的把这个问题从O(n^2)优化到了O(n)

复杂度 O(n)

#include <iostream>
#include <cstdio>
#include <map>
#include <cmath>
using namespace std;
typedef long long LL;
typedef pair<int, int> ii;
const int MAXN = 1e5 + 8;
const LL INF = 1e14 + 8;

map<LL, LL> mp;
LL a[MAXN], pow_k[66];

int main()
{
#ifdef LOCAL
freopen("c.txt", "r", stdin);
//freopen("c.out", "w", stdout);
int T = 4;
while(T--){
#endif // LOCAL
ios::sync_with_stdio(false); cin.tie(0);

LL n, k, cnt, i, j, ans = 0, sum = 0;
cin >> n >> k;
for(i = 1; i <= n; i++) cin >> a[i];
if(k == 1){cnt = 1; pow_k[0] = 1;}
else if(k == -1){cnt = 2; pow_k[0] = 1; pow_k[1] = -1;}
else{
pow_k[0] = 1;
for(i = 1; i < 66; i++){
if(abs(pow_k[i-1]*k) >= INF){cnt = i; break;}
pow_k[i] = pow_k[i-1] * k;
}
}
mp[sum]++;
for(i = 1; i <= n; i++){
sum += a[i];
for(j = 0; j < cnt; j++){
ans += mp[sum - pow_k[j]];
}
mp[sum]++;
}
cout << ans << endl;

#ifdef LOCAL
mp.clear();
cout << endl;
}
#endif // LOCAL
return 0;
}



Thank you!

                                                                                                           
                                 ------from ProLights
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐