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

本文介绍了一个算法问题,即寻找数组中连续子数组的个数,使得这些子数组的元素之和为给定整数k的非负整数次幂。通过使用哈希表记录前缀和,实现了有效的解决方案。

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;
}
### C/C++中包含`icm20608.h`头文件时出现报错的解决方案 在C/C++项目中,当尝试包含`icm20608.h`头文件时遇到报错问,通常可能涉及以下几个方面的原因及解决方法: #### 1. 头文件路径问 如果编译器无法找到`icm20608.h`头文件,则会报错。这种情况下需要确保头文件的路径已被正确配置。可以通过以下方式解决: - 确保`icm20608.h`文件位于当前源文件所在目录下,或者位于标准头文件搜索路径中。 - 如果头文件位于非标准路径下,需使用`-I`选项指定额外的头文件搜索路径。例如,假设`icm20608.h`位于`/usr/local/include/icm20608/`目录下,则可以在编译命令中添加`-I/usr/local/include/icm20608/`[^1]。 ```bash gcc -o main main.c -I/usr/local/include/icm20608/ ``` #### 2. 头文件内容错误或不完整 如果`icm20608.h`本身存在语法错误或定义不完整,也可能导致编译失败。此时应检查头文件内容是否符合C/C++规范,并确保所有依赖的宏、类型和函数声明均已正确定义。 #### 3. 编译器版本或标准库兼容性问 某些头文件可能依赖特定版本的编译器或标准库。如果使用的编译器版本较低或未启用正确的语言标准(如C99、C11或C++11),可能会导致编译失败。可以尝试以下方法: - 指定编译器语言标准。例如,对于GCC编译器,可以使用`-std=c99`或`-std=c++11`选项[^2]。 ```bash gcc -o main main.c -std=c99 ``` - 更新编译器到最新版本,以支持更多现代语言特性。 #### 4. 链接阶段问 即使头文件包含成功,如果缺少对应的实现文件(如`.c`或`.cpp`文件)或库文件,链接阶段仍可能出现错误。确保以下事项: - 实现文件已正确编译并链接到最终目标文件中。 - 如果`icm20608.h`依赖外部库,需确保这些库已正确安装并在链接时指定。例如,假设`icm20608`依赖于`libi2c`库,则需要在链接时添加`-li2c`选项[^3]。 ```bash gcc -o main main.c -I/usr/local/include/icm20608/ -li2c ``` #### 示例代码 以下是一个简单的示例,展示如何正确包含和使用`icm20608.h`头文件: ```c #include "icm20608.h" int main() { // 初始化ICM20608传感器 if (icm20608_init() != 0) { printf("Failed to initialize ICM20608\n"); return -1; } // 读取加速度数据 icm20608_data_t data; icm20608_read_accel(&data); printf("Acceleration: X=%f, Y=%f, Z=%f\n", data.ax, data.ay, data.az); return 0; } ``` ### 注意事项 - 确保`icm20608.h`及其相关实现文件来自可信来源,并与硬件设备匹配。 - 如果使用的是第三方库,参考其官方文档以获取更详细的配置说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值