C. Molly's Chemicals 暴力 + 统计技巧

http://codeforces.com/contest/776/problem/C

一开始做的时候,就发现是预处理前缀和,然后对于每一个前缀和,如果他能成为一个贡献,就是能和前面的某些段

组合成和为k^x的话,那么需要cur_per_sum - val = k^x,这样可以解出val是多少,去前面找有多少个数是val就行了。

然后开始的时候我是先把所有数字都预处理然后放入map的,这样的做法是不对的,变得十分麻烦,

可能前面的前缀和是0,然后后面的前缀和也是0,但是当前枚举的这一位不能和后面的组合,这样就会GG。

所以可以枚举cur的时候,把cur - 1的东西放入去先,这样就不会被后面的影响。

记得特判1和-1的情况,特别是-1

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e5 + 20;
map<LL, int>mipos;
map<LL, int>num;
const LL uppos = 1e14;
const LL upnag = -1e14;
LL sum;
LL mypow(LL k, LL b) {
    LL ans = 1;
    for (int i = 1; i <= b; ++i) {
        ans *= k;
    }
    return ans;
}
void work() {
    int n;
    LL k;
    cin >> n >> k;
    num[0] = 1;
    LL ans = 0;
    for (int i = 1; i <= n; ++i) {
        int x;
        cin >> x;
        sum += x;
        int sel = 0;
        for (int j = 0; ; ++j) {
            LL now = mypow(k, j);
            if (now > uppos) break;
            if (now < upnag) break;
            ans += num[sum - now];
            sel++;
            if (k == 1) break;
            if (k == -1 && sel == 2) break;
        }
        num[sum]++;
    }
    cout << ans << endl;
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    IOS;
    work();
    return 0;
}
View Code

 

posted on 2017-02-24 12:14  stupid_one  阅读(225)  评论(0编辑  收藏  举报

导航