题目链接:传送门

题目大意:给你n个整数(可正可负),求有多少个连续的子序列的和==m(时限1S)

题目思路:前缀和+手写hash(map效率太慢,会超时)

具体做法是用一个数组sum,数组的第i位保存前1~i个数的和,那么从第x个元素到到第y个元素的和就可以表示为sum[y]-sum[x]

现在我们要求有多少个连续子序列的和==m,也就是找出有多少个sum[y]-sum[x]==m。

     如果给你的数都是正整数就好办了,不难想到可以用尺取法(双指针扫描),但是难点在于有负数,也就是sum数组的值很杂乱。

但其实,我们观察一下式子    sum[y]-sum[x]==m,如果把它转换一下   sum[y]-m=sum[x]。那么我们对于sum[i],只需要找到

在i之前出现了多少sum[i]-m,答案就加上sum[i]-m的个数,所以我们只需从头扫一遍即可。复杂度O(n),但是map效率太慢,所以还需

手写hash

MAP超时代码

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#include <stack>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <map>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int mod = ;
const int N = 1e6 + ;
map<ll, int> mp; ll sum[N];
int main() {
int n, m, v;
int group; scanf("%d", &group);
while(group--) {
scanf("%d%d", &n, &m);
sum[] = ;
for(int i = ; i <= n; ++i) {
scanf("%d", &v);
sum[i] = sum[i - ] + v;
}
int ans = ;
mp.clear(); mp[] = ;
for(int i = ; i <= n; ++i) {
ll s = sum[i] - m;
int num = mp[s];
ans += num; mp[sum[i]]++;
}
printf("%d\n", ans);
}
return ;
}

AC代码

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#define mst(x,y) memset(x,y,sizeof(x))
using namespace std;
const long long MOD=(1ll<<);
const long long MMM=;
const int N=; int n,m;
long long key[N],sum[N];
int head[MMM],cnt[N],next[N],hcnt;
struct Myhas{
void init(){
mst(head,-);
mst(cnt,);
hcnt=;
}
void ins(long long x){
int h=x%MMM;
key[hcnt]=x;
cnt[hcnt]=;
next[hcnt]=head[h];
head[h]=hcnt++;
}
void add(long long x){
int h=x%MMM;
for(int i=head[h];~i;i=next[i]){
if(key[i]==x){++cnt[i];return;}
}
}
int query(long long x){
int h=x%MMM;
for(int i=head[h];~i;i=next[i]){
if(key[i]==x) return cnt[i];
}
return -;
}
}has;
int main(){
int i,j,group,x,ans;
scanf("%d",&group);
while(group--){
scanf("%d%d",&n,&m);
for(i=;i<=n;++i){
scanf("%d",&x);
sum[i]=sum[i-]+x;
}
ans=;
has.init();
has.ins(MOD);
for(i=;i<=n;++i){
long long xx=sum[i]-m+MOD;
int num=has.query(xx);
if(num!=-)ans+=num;
xx=(sum[i]+MOD);
if(has.query(xx)!=-)has.add(xx);
else has.ins(xx);
}
printf("%d\n",ans);
}
return ;
}

FZU1465的更多相关文章

随机推荐

  1. (三)Solr——Solr的基本使用

    1. Schema.xml 在schema.xml文件中,主要配置了solrcore的一些数据信息,包括Field和FieldType的定义等信息,在solr中,Field和FieldType都需要先 ...

  2. Workshop:用Python做科学计算

    Python是程序史上最流行的开源语言之一. 仅在官方包索引PyPi上就已经发布了超过10万个开源软件包,而且还有更多的项目. 在SciPy的麾下,有一个成熟的python包生态系统,可以使用Pyth ...

  3. 【干货】电路设计师指导手册(已更新完毕)(转载EDN)

    [干货]电路设计师指导手册(已更新完毕) 第一部分:接地与布线第二部分:电源返回路径与I/O信号接地第三部分:板间互连.星形接地及屏蔽第四部分:安全地以及电线/电缆第五部分:射频电缆.双绞线与串扰

  4. Chrome应用技巧之颜色拾取

    之前在Chrome应用店找了个插件实现拾色功能.并且很不理想.不知道是不是曾经Chrome自带的开发工具没提供到拾色功能还是我没发现.今天无意中发现Chomer自带的开发工具可拾色,请看以下的GIF动 ...

  5. size_t详细解释

    在学习sizeof运算符的时候,它的值类型为size_t,结果在使用printf函数显示的时候,凭空多了很多警告,有点不不理解,为啥搞这么复杂?直接用个int类型多省事? 经过一番搜索和阅读文档,找到 ...

  6. G1日志分析

    1. 概述 来自对官方G1垃圾收集器的日志解释分析,官方地址:https://blogs.oracle.com/poonam/understanding-g1-gc-logs或https://blog ...

  7. atitit.session的原理以及设计 java php实现的异同

    atitit.session的原理以及设计 java php实现的异同 1. session的保存:java在内存中,php脚本因为不能常驻内存,所以在文件中 1 2. php的session机制 1 ...

  8. redis命令_ZREVRANGEBYSCORE

    ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] 返回有序集 key 中, score 值介于 max 和 min 之间(默 ...

  9. 基于C#和Asp.NET MVC开发GPS部标视频监控平台

    基于C#和Asp.NET MVC开发GPS部标监控平台 目前整理了基于.NET技术的部标平台开发文章,可以参考: 1.部标Jt808协议模拟终端的设计和开发 2.C#版的808GPS服务器开发-> ...

  10. Vmware虚拟机修改静态IP无法ping外网,以及eth0不见问题解决

    1. 修改静态地址后发现无法ping外网 要先把/etc/sysconfig/network-scripts/ifcfg-eth0中的网关设置成192.168.230.2. 需要设置网关 sudo r ...