FZU1465
题目链接:传送门
题目大意:给你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的更多相关文章
随机推荐
- 从MVC和三层架构说到ssh整合开发-下
这章主要讲整合开发,直接从实战讲起,对与ssh的单方面了解,请继续等待我的兴许文章. 解说不到位的地方欢迎大家指正:联系方式rlovep.com 具体请看源码凝视: 全部代码下载(csdn):链接 G ...
- git 教程一
git 是一个开源的分布式版本控件系统,用于敏捷高效地处理任何或小或大的项目. Git是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件. Git 与常用 ...
- Objective-C之定义函数
Demo1.m 一个基础的函数定义 #import<Foundation/Foundation.h> //定义一个返回值为int类型的,名为max的函数.传入的参数为两个int型数据 in ...
- object-c输出对象
有时候在xcode里打断点很不准,看到对象总是nil,还是用打log比较靠谱: NSLog(@"obj info:%@",obj);
- OZ Report 오즈 리포트 개발
//这只单元格数据颜色 if( (int)getattr("caption") > 100) setattr("bgcolor", "$0,0, ...
- C# asp.net页面常用语法,页面包含
搞.net开发这么多年,知道和用过包含include指令吗? <%@ Page Language="C#" AutoEventWireup="true" ...
- C语言中的传值调用
在c语言中每个变量都有两个属性一个是值,一个是址. 比方: int a = 2; 变量a的值是2,变量a的地址,能够用&取地址操作符获取,即&a. 因此以C语言的函数传递中具备两种方式 ...
- JavaScript No Overloading 函数无重载之说
在ECMAScript语言中,函数名字仅仅只是是一个指针(能够觉得是引用),以下的代码: "use strict"; function sum(a,b){ return a+b; ...
- CSU 1329: 一行盒子
1329: 一行盒子 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 740 Solved: 145[Submit][Status][Web Board ...
- iOS开发多线程篇 05 —GCD介绍
iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 G ...