ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) C. Molly's Chemicals

Molly’s Chemicals
time limit per test 2.5 seconds
memory limit per test 512 megabytes

Description

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 of k. 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.

Input

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

Output a single integer — the number of valid segments.

Sample Input
4 2
2 2 2 2

Sample Output
8

cf开virtual写到这道题的时候感觉题面很简单,感觉上和自己昨天写的一道莫队的题目很相似,那道题目是让你找有多少个区间的区间和是0,这道题是找有多少个区间的区间和是k的整数次幂。这道题的n的范围是1e5,那莫队n*sqrt(n)肯定是解决不了的.
仔细想了一下这样找区间多半是O(n)的查询,因为个人感觉在这里二分区间也没啥用。O(n)的查询的话,我们记录一下每一位的前缀和,做差便得到了两个下标间的区间和。在这里发散一下思维,如果我们用map哈希的记录前缀和数值是否存在,这样对每一位k的幂级数而言,我们只要O(n)的就能找出是否存在该区间和。
k的范围是[-10~10]真的是深坑啊,在预处理k的幂级数的时候忘了考虑-1和1的情况了,导致一直while死循环re了5发⊙︿⊙
这样最多62*n的时间复杂度下便可得到正解。

唉,这题wa了11发才过,最近的bug率很高啊,该调整心态了。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#include<limits.h>
#include<string.h>
#include<map>
using namespace std;
typedef long long ll;

#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define eps double(1e-6)
#define pi acos(-1.0)
#define lson  root << 1
#define rson  root << 1 | 1



ll n,k;

ll a[100005];

map<ll,ll> mp;

vector<ll> mi;



ll powmod(ll a,ll b)
{
    ll ans = 1;
    while(b)
    {
        if(b&1)
        {
            ans = (ans*a);
            b--;
        }
        b/=2;
        a = a*a;
    }
    return ans;
}

void init(ll k)
{
    int cnt=0;
    while(1)
    {
        //cout<<111<<endl;
        if(k==-1)
            mi.push_back(-1);
        if(k==-1||k==1)
        {
            mi.push_back(1);
            break;
        }
        else
        {
            mi.push_back(powmod(k,cnt));
            cnt++;
            //cout<<pos<<endl;
            ll shu=powmod(k,cnt-1);
            if(shu>=1e15)
                break;
        }
    }
}

int main()
{
    //cout<<powmod(-1,2)<<endl;
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    memset(a,0,sizeof(a));
    for(ll i=1; i<=n; i++)
    {
        cin>>a[i];
        a[i]+=a[i-1];
    }
    init(k);
    ll sum=0;
    //cout<<mi[0]<<endl;
    //cout<<pos<<endl;
    for(ll i=0; i<mi.size(); i++)
    {
        //cout<<mi[i]<<endl;
        //cout<<111<<endl;
        mp.clear();
        ll pownum=mi[i];
        for(ll j=1; j<=n; j++)
        {
            //cout<<a[j-1]<<endl;
            mp[a[j-1]]++;
            if(mp.count(a[j]-pownum))
            {
                sum+=mp[a[j]-pownum];
                //cout<<mp[a[j]-pownum]<<endl;
            }
        }
    }
    cout<<sum<<endl;
}

猜你喜欢

转载自blog.csdn.net/murphyc/article/details/79217521