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
output
input
output
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
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
相关文章推荐
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) A map B贪心 C思路前缀
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- 【枚举】【前缀和】【map】ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) C. Molly's Chemicals
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- 【前缀和 && 思维转换】ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined)Molly's Chemicals
- Codeforces Round #400 (Div. 1 + Div. 2, combined) C - Molly's Chemicals 区间和问题
- ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) 解题报告
- Codeforces Round #400 (Div. 1 + Div. 2, combined)A. A Serial Killer【模拟】
- Codeforces Round #400 (Div. 1 + Div. 2, combined)D - The Door Problem(2-sat)