Codeforces Round #400 Molly's Chemicals 前缀和
来源:互联网 发布:河北农业科技网络书屋 编辑:程序博客网 时间:2024/05/17 06:26
题目:
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 ofk. 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.
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 a single integer — the number of valid segments.
4 22 2 2 2
8
4 -33 -6 -3 12
3
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].
这种求多少个区间满足条件的题,一直是我的一大软肋,0rzzz。
设sum[i]=sigma(a[0...i]) (其实i表示的就是前前缀和的右端点) 这个题意思就是,求sum[j]-sum[i]=k^p(p=0,1,2,3...)(j>=i)。
我自己能想到的解法也就只有暴力枚举了i,j了,O(n^2)还是死了这条心吧。其实还是枚举,不过我们得换一个姿势。
注意到k^p不超过1e14,那么最差情况下(1,-1分别讨论),我们需要枚举幂p [log2 (1e14)]+1<50故,我们可以考虑枚举p和右前缀和的右端点j也就是说 sum[j]-k^p=sum[i],sum[i]有几个答案ans就加上几,考虑用map存储个数。
code:
#include<cmath>
#include<map>
#include<cstdio>
using namespace std;
typedef long long LL;
const int MAXN=1e5+5;
const LL INF=1e15+5;
LL sum[MAXN];
map<LL,int>cnt;
int main(){
LL n,k;scanf("%I64d%I64d",&n,&k);
sum[0]=0;
for(int i=1;i<=n;++i){
LL a;scanf("%I64d",&a);
sum[i]=sum[i-1]+a;
}
LL res=0;
if(k==1){
for(int i=0;i<=n;++i){
cnt[sum[i]]++;//1的不论多少次方都是1
res+=cnt[sum[i]-1];
}
}
else if(k==-1){
for(int i=0;i<=n;++i){
cnt[sum[i]]++;//-1的奇数次方是-1,偶数次方是1
res+=cnt[sum[i]-1]+cnt[sum[i]+1];
}
}
else {
for(int i=0;i<=n;++i){//枚举前缀和右端点
cnt[sum[i]]++;
LL val=1;//val 代表k的p次方的值
for(;;){//枚举k^p
res+=cnt[sum[i]-val];
val*=k;
if(val>INF||val<-INF)break;
}
}
}
printf("%I64d\n",res);
}
其实在写这个题期间我还犯了一个巨大的错误:
sum[0]=0; cnt[0]++;
for(int i=1;i<=n;++i){
LL a;scanf("%I64d",&a);
sum[i]=sum[i-1]+a;
cnt[sum[i]]++;
}
然后像这样枚举。
int res=0;
for(int i=0;i<=n;++i)
for(int p=0;;++p){
LL val=pow(k,p);
if(val>INF||val<-INF)break;
res+=cnt[sum[i]-val];//tag
if(cnt[sum[i]-val]>=1){
//printf("sum[i]=%I64d,val=%I64d\n",sum[i],val);
}
错误的原因在于没理解到时枚举右端点,在tag处得到的值可能跑到右端点右边去了,这显然会重复。下次注意吧。
题外话:每次看前面的哪些神牛的代码都太感叹了。能够在这么短的时间内写出这么对的优雅的代码。贴一个ainta的
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
map<long long, int>Map;
int n, K;
long long s, res, t;
int main(){
int a, i;
scanf("%d%d",&n,&K);
Map[0] = 1;
for(i=1;i<=n;i++){
scanf("%d",&a);
s += a;
if(K==1){
res += Map[s-1];
}
else if(K==-1){
res += Map[s-1] + Map[s+1];
}
else{
t = 1;
while(1){
res += Map[s-t];
t*=K;
if(t > 1e15 || -t > 1e15)break;
}
}
Map[s]++;
}
printf("%lld\n",res);
}
- Codeforces Round #400 Molly's Chemicals 前缀和
- Codeforces Round #400 C. Molly's Chemicals(前缀和)
- Codeforces Round #400 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(前缀+思维)
- codeforces 776C Molly's Chemicals(前缀和 二分搜索)
- Codeforces 776C Molly's Chemicals 前缀和
- 【Codeforces 776 C Molly's Chemicals】+ 前缀和 + map
- Codeforces-776C-Molly's Chemicals(前缀和)
- 【Codeforces 776 C. Molly's Chemicals】+ map + 前缀和
- Codeforces Round #400 C. Molly's Chemicals (二分)
- Codeforces Round #400 C. Molly's Chemicals [二分]
- Molly's Chemicals CodeForces
- Molly's Chemicals CodeForces
- CodeForces 776C Molly's Chemicals (思维+前缀)
- CF 776C Molly's Chemicals 前缀和,STL
- ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) C. Molly's Chemicals
- Linux服务器安全登录注意事项
- PHP foreach的两种用法
- Struts Spring com/opensymphony/xwork2/spring/SpringObjectFactory.java:220:-1 的一点解决办法
- Spring mvc 原理及流程图
- [OpenGL] 你好,GLSL
- Codeforces Round #400 Molly's Chemicals 前缀和
- 胡适:赠与今年的大学毕业生
- 页面渲染优化的过程
- Predict the Winner
- SequenceFile & MapFile
- 如何修改maven的默认jdk版本
- Linux环境下如何编译和运行opencv程序
- Nodejs 模块安装:
- spark RDD算子(十一)之RDD Action 保存操作saveAsTextFile,saveAsSequenceFile,saveAsObjectFile,saveAsHadoopFile 等