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的更多相关文章
随机推荐
- IOS后台文件上传
public ModelAndView GetImage(HttpServletRequest request, HttpServletResponse response) throws Exce ...
- PHP连接Azure Redis
概述 Azure Redis缓存基于流行的开源Redis缓存,可以通过各种Redis客户端进行访问,这些客户端适用于许多编程语言.每个客户端有自身的API,用于通过Redis命令调用Redis缓存实例 ...
- int.TryParse非预期执行引发的思考
问题出现 这天在写一个页面,想谨慎些就用了int.TryParse,结果出问题了. 代码如下: int id = 1000; //Request.QueryString["id"] ...
- simpleRNN
simpleRNN 训练集为<爱丽丝梦境>英文版txt文档,目标:根据随机给出的10个字符,生成可能的后100个字符 词向量空间生产 In [4]: INPUT_FILE = " ...
- javascript 反调试 监听用户打开了Chrome devtool
let div = document.createElement('div'); let loop = setInterval(() => { console.log(div); ...
- NIO - Selector源码分析
1. 背景 SelectableChannel对象的多路复用器. 可以通过调用Selector.open()方法创建Selector对象.Selector.open()方法会利用系统默认的Select ...
- sourceInsight设置
复制后光标定格在行尾 Options -> Preferences -> Typing -> After pasting,select:at end of pasted text t ...
- matplotlib之极坐标系的极角网格线(thetagrids)的显示刻度
极坐标系的极角网格线(thetagrids)的显示刻度 #!/usr/bin/env python3 #-*- coding:utf-8 -*- ########################### ...
- 广告过滤神器(ADMuncher)4.93
Ad Muncher 介绍: 浏览网页时,冷不防地被网站播放的MIDI音乐声音吓一跳,或是因为弹出的广告窗口碍事,而影响你上网络的心情.Ad Muncher支持Netscape.Inte ...
- HTML5坦克大战(2)绘制坦克复习
html代码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head&g ...