题目链接:传送门

题目大意:给你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. Android studio 使用心得(五)—代码混淆和破解apk

    这篇文章等是跟大家分享一在Android studio 进行代码混淆配置.之前大家在eclipse上也弄过代码混淆配置,其实一样,大家可以把之前在eclipse上的配置文件直接拿过来用.不管是.cfg ...

  2. Android工程:引用另一个Android工程的方法详解

    本篇文章是对在Android中引用另一个Android工程的方法进行了详细的分析介绍.需要的朋友参考下   现在已经有了一个Android工程A.我们想扩展A的功能,但是不想在A的基础上做开发,于是新 ...

  3. 在Windows8系统下exe格式会计课件下载播放帮助图解

    近期非常多会计从业人员都開始购买课件,開始学习,准备考试:可是网校的课件有些是EXE扩展名格式的,在Windows8系统下播放比較困难.方法比較曲折,这里用图说话,给大家一点參考,希望对大家实用. 下 ...

  4. jquery cookie操作方法

    1. 设置cookie的值,把name变量的值设为value     $.cookie(’name’, ‘value’);  2.新建一个cookie 包括有效期 路径 域名等 $.cookie(’n ...

  5. JNI调用实例

    1. 环境 Windows7-64Bit VS2010-32Bit JDK1.8-64Bit 2. 步骤 2.1 创建NativePrint类 public class NativePrint { p ...

  6. numpy.meshgrid()理解

    本文的目的是记录meshgrid()的理解过程: step1. 通过一个示例引入创建网格点矩阵; step2. 基于步骤1,说明meshgrid()的作用; step3. 详细解读meshgrid() ...

  7. [NM 状态机1] Application状态机详解

    概述 前面已经分析了RM的状态机,接下来将分析NM的状态机,NM状态机包括Container,Application,LocalizedResource三个.首先我们分析Application的状态机 ...

  8. HTML5七巧板canvas绘图(复习)

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  9. 【Spring】java.lang.IndexOutOfBoundsException: Index: 256, Size: 256

    Spring接受前台的数据超过256出现例如以下异常: org.springframework.beans.InvalidPropertyException: Invalid property 'sp ...

  10. Practial Vim 学习笔记一

    . 号作用是重复上一个动作. >+G  缩进 j 光标下移 u 撤销操作 $ 光标移到行尾 x 删除光标下的字符 dd 删除整行 i 切换到Insert模式 Esc 返回 f 将光标移到下个字符 ...