首页 > 技术文章 > codeforces 776C Molly's Chemicals(连续子序列和为k的次方的个数)

WHLdbk 2017-03-05 20:11 原文

题目链接

题意:给出一个有n个数的序列,还有一个k,问在这个序列中有多少个子序列使得sum[l, r] = k^0,1,2,3……

思路:sum[l, r] = k ^ t, 前缀和sum[r] = sum[l-1] + k^t。即如果后面有一段序列使得sum[l,r] = k^t,那么它可以转化为前缀和相减使得这一段大小为k^t,即sum[i] = sum[j] + k^t (1 <= j < i)。

那么对于处理好的每一个前缀和,直接往后面加上k^t(0<=t<=x,k^x是不超过题目范围的数)。然后在后面遍历的时候直接加上对应那个数的权值。

因为数据很大,所以只能用map来装权值。

代码实现:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll f[101005];
 5 ll k_t[1000];
 6 int main()
 7 {
 8     int n,k,i,j,cnt;
 9     while(cin>>n>>k)
10     {
11         map<ll,int>mp;
12         memset(f,0,sizeof(f));
13         memset(k_t,0,sizeof(k_t));
14         for(i=1;i<=n;i++)
15         {
16             cin>>f[i];
17             f[i]+=f[i-1];
18         }
19         k_t[1]=1;cnt=2;
20         if(k==-1)k_t[2]=-1,cnt++;
21         else if(k!=1)
22         {
23             ll temp=k;
24             while(temp<1e15)
25             {
26                 k_t[cnt++]=temp;
27                 temp*=k;
28             }
29         }
30         ll ans=0;
31         for(i=1;i<cnt;i++)mp[k_t[i]]=1;
32         for(i=1;i<=n;i++)
33         {
34             if(mp[f[i]])ans+=mp[f[i]];
35             for(j=1;j<cnt;j++)
36             mp[f[i]+k_t[j]]++;
37         }
38         cout<<ans<<endl;
39     }
40     return 0;
41 }

 

推荐阅读