zoukankan      html  css  js  c++  java
  • Codeforces 776C

    题目大意:给出n个数(a1.....an),和一个数k,问有多少个区间的和等于k的幂 (1 ≤ n ≤ 10^5, 1 ≤ |k| ≤ 10, - 10^9 ≤ ai ≤ 10^9)

    解题思路:首先,可以从题目得出k的幂最大不能超过n*ai=1e14。然后,我们先求出前缀和sum[1]...sum[n],k的i次幂为power[i]。我们要求出一个区间和等于power[i]即sum[r]-sum[l]=power[i],转换一下sum[r]=sum[l]+power[i]。

    所以我们只需要从1到n遍历一遍,记录下sum[r]的出现次数,用map存起来,即map[sum[i]+power[i]]++。最后如果sum[r]可以从我们的sum[1]到sum[n]这些前缀和里找到,那就把ans+=map[sum[r]]。

    代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<map>
     4 using namespace std;
     5 typedef long long ll;
     6 const int N = 1e5 + 5;
     7 
     8 ll sum[N];//前缀和
     9 ll power[60];
    10 
    11 int main() {
    12     ll n, k;
    13     cin >> n >> k;
    14     sum[0] = 0;
    15     map<ll, ll>mp;
    16     for (int i = 1; i <= n; i++) {
    17         cin >> sum[i];
    18         sum[i] += sum[i - 1];
    19     }
    20 
    21     ll t = 1;
    22     ll cnt = 0;
    23     power[0] = 1;
    24     //1和-1需要特判 
    25     if (k == 1 || k == -1) {
    26         if (k == -1) {
    27             power[1] = -1;
    28             cnt++;
    29         }
    30     }
    31     else {
    32         for (int i = 1; i <= 50; i++) {
    33             t *= k;
    34             if (t>1e14)
    35                 break;
    36             power[++cnt] = t;
    37         }
    38     }
    39     //sum[l]=0时的情况
    40     for (int i = 0; i <= cnt; i++) {
    41         mp[power[i] + 0]++;
    42     }
    43 
    44     ll ans = 0;
    45     for (int i = 1; i <= n; i++) {
    46         //计算ans一定要写在这里
    47         ans += mp[sum[i]];
    48         //记录sum[r]=sum[l]+power[j]的出现次数
    49         for (int j = 0; j <= cnt; j++) {
    50             mp[sum[i] + power[j]]++;
    51         }
    52     }
    53     cout << ans << endl;
    54     /*这种写法是错误的,因为sum[r]一定在sum[l]之后,可能出现sum[l]+power[i]得到的值不在sum[l]后面,
    55     而在sum[l]前面,那么也就不满足是sum[r]的条件了,下面这样写就会把这种情况也记录在内了。
    56     for (int i = 1; i <= n; i++) {
    57         ans += mp[sum[i]];
    58     }
    59     cout << ans << endl;
    60     */
    61     return 0;
    62 }
  • 相关阅读:
    Live Writer配置
    protobufnet 学习手记
    好的Sql语句也能提高效率(二)
    关于CodeSmith的输出问题
    [Scrum]12.29
    [scrum] 1.4
    分享 关于c#注释的规范
    [Scrum] 1.3
    分享:将XML(VS提取注释时生成)转换为Chm的一个方法
    【Scrum】2010.12.27
  • 原文地址:https://www.cnblogs.com/fu3638/p/7106392.html
Copyright © 2011-2022 走看看