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 }
  • 相关阅读:
    瀑布流布局(等宽不等高jQuery)
    多组图自动无限循环(swiper轮播)
    $.ajax的标准写法
    走马灯特效
    如何使用js改变HTML中title里面固定的文字
    test
    单例设计模式
    线程的五种状态(线程的生命周期)
    Net基础班第十三天
    装箱、拆箱
  • 原文地址:https://www.cnblogs.com/fu3638/p/7106392.html
Copyright © 2011-2022 走看看