题意:问有没有数对(i,j)(0<=i<=j<n),使得a[i]-a[i+1]+...+(-1)^(j-i)a[j]为K.

解法:两种方法,枚举起点或者枚举终点。

先保存前缀和:a1-a2+a3....+/- an

枚举起点法: 设起点为x,实际是枚举x-1,分两种情况:

1.起点x为奇,那么就看有没有a[j]-a[x-1] = K的,即a[j] = a[x-1]+K。因为奇数位置的ai数符为正。

2.起点x为偶,那么就看有没有a[j]-(-K) = a[x-1],即a[j] = a[x-1]-K。因为偶数位置ai数符为负,即x到j这一段的数是负的 选x为起点的x到j的这一段和,所以中间实际上是-K。

每次将sum[i]标记为出现过。

只需要一个hashmap即可。

由于枚举到一个起点x,需要判断a[j](j>x)是否出现,所以要逆序枚举。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define Mod 1000000007
#define lll __int64
#define ll long long
using namespace std;
#define N 1000007 lll sum[N];
const unsigned long long SMod=;
struct hashmap{
struct Edge
{
long long num;
int next;
};
Edge edge[*N];
int countedge;
int head[SMod+]; void init()
{
memset(head,-,sizeof(head));
countedge=;
} void addedge(long long num)
{
int start=num%SMod;
edge[countedge].next=head[start];
edge[countedge].num=num;
head[start]=countedge;
countedge++;
} int Find(long long num)
{
int start=num%SMod;
int ind;
for(ind=head[start]; ind!=-; ind=edge[ind].next)
{
if(edge[ind].num==num)break;
}
return ind;
}
}ST; int main()
{
int n,i,j,cs = ,t,x,K;
scanf("%d",&t);
while(t--)
{
ST.init();
scanf("%d%d",&n,&K);
sum[] = ;
for(i=;i<=n;i++) {
scanf("%d",&x);
if(i%) sum[i] = sum[i-] + x;
else sum[i] = sum[i-] - x;
}
ST.addedge(sum[n]);
int tag = ;
for(i=n-;i>=;i--) {
if(i% == && ST.Find(sum[i]+K) != -) { tag = ; break; }
if(i% && ST.Find(sum[i]-K) != -) { tag = ; break; }
ST.addedge(sum[i]);
}
printf("Case #%d: ",cs++);
if(tag) puts("Yes.");
else puts("No.");
}
return ;
}

枚举终点法

建立两个hashmap,一个记录sum[1],sum[3],...sum[2*cnt+1] (2*cnt+1<=n)即奇数位置是否出现过,另一个记录偶数位置的sum值是否出现过。

枚举终点y的话,起点可能是1~y的任何一个(这里下标从题目中的0~n-1转为了1~n),当起点x=1的时候,这时NP-SUM(x,y) = sum[y], 记为XX。以n=4为例。

那么起点为2的时候整个值就等于 -XX+a1, (-(a1-a2+a3-a4) +a1 = a2-a3+a4))

起点为3的时候整个值等于 XX-sum[2]      (a1-a2+a3-a4 - (a1-a2) = a3-a4 )

...以此类推,归为两类 :

1. XX-sum[0] , XX-sum[2] , ... XX-sum[偶数] 是否为K

2. -XX+sum[1], -XX+sum[3], ... -XX+sum[奇数] 是否为K

设他们为K,那么即判断 XX-K在偶数的hashmap中有没有出现, 判断XX+K在奇数的hashmap中有没有出现。

每次将sum[i]加入到对应的hashmap中。

顺序枚举。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define Mod 1000000007
#define lll __int64
#define ll long long
using namespace std;
#define N 1000007 const unsigned long long SMod=;
struct hashmap{
struct Edge
{
long long num;
int next;
};
Edge edge[*N];
int countedge;
int head[SMod+]; void init()
{
memset(head,-,sizeof(head));
countedge=;
} void addedge(long long num)
{
int start=num%SMod;
edge[countedge].next=head[start];
edge[countedge].num=num;
head[start]=countedge;
countedge++;
} int Find(long long num)
{
int start=num%SMod;
int ind;
for(ind=head[start]; ind!=-; ind=edge[ind].next)
{
if(edge[ind].num==num)break;
}
return ind;
}
}mpe,mpo; int main()
{
int n,i,j,cs = ,t,x,K;
scanf("%d",&t);
for(cs=;cs<=t;cs++)
{
mpo.init();
mpe.init();
scanf("%d%d",&n,&K);
lll sum = ;
mpe.addedge();
int tag = ;
for(i=;i<=n;i++) {
scanf("%d",&x);
if(i&) sum += x;
else sum -= x;
if(i&) mpo.addedge(sum);
else mpe.addedge(sum);
if(mpe.Find(sum-K) != -) { tag = ; }
if(mpo.Find(sum+K) != -) { tag = ; }
}
printf("Case #%d: ",cs);
if(tag) puts("Yes.");
else puts("No.");
}
return ;
}

注意:

如果hashmap中的SMod 用宏定义的方式就会T, 用const unsigned long long 就不会。不知道为什么。

hashmap模板借鉴了love_dn的代码。

HDU 5183 Negative and Positive (NP) --Hashmap的更多相关文章

  1. hdu 5183 Negative and Positive (NP)

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5183 Negative and Positive (NP) Description When give ...

  2. HDU 5183 Negative and Positive (NP) (手写哈希)

    题目链接:HDU 5183 Problem Description When given an array \((a_0,a_1,a_2,⋯a_{n−1})\) and an integer \(K\ ...

  3. HDU 5183 Negative and Positive (NP) (hashmap+YY)

    学到了以邻接表方式建立的hashmap 题意:给你一串数a和一个数k,都有正有负,问知否能找到一对数(i,j)(i<=j)保证a [i] - a [i+1] + a [i+2] - a [i+3 ...

  4. HDU 5183 Negative and Positive (NP) 前缀和+哈希

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5183 bc(中文):http://bestcoder.hdu.edu.cn/contests ...

  5. HDU 5183 Negative and Positive (NP) ——(后缀和+手写hash表)

    根据奇偶开两个hash表来记录后缀和.注意set会被卡,要手写hash表. 具体见代码: #include <stdio.h> #include <algorithm> #in ...

  6. hdu 5183 Negative and Positive (NP)(STL-集合【HASH】)

    题意: When given an array (a0,a1,a2,⋯an−1) and an integer K, you are expected to judge whether there i ...

  7. hdu 5183. Negative and Positive (哈希表)

    Negative and Positive (NP) Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  8. [HDOJ 5183] Negative and Positive (NP) 【Hash】

    题目链接:HDOJ - 5183 题目分析 分两种情况,奇数位正偶数位负或者相反. 从1到n枚举,在Hash表中查询 Sum[i] - k ,然后将 Sum[i] 加入 Hash 表中. BestCo ...

  9. hdu 5183(hash)

    传送门:Negative and Positive (NP) 题意:给定一个数组(a0,a1,a2,⋯an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP− ...

随机推荐

  1. 在公有云AZURE上部署私有云AZUREPACK以及WEBSITE CLOUD(一)

    (一)前言 本文主要介绍了实践部署AzurePack的Website Cloud的过程.在部署之前, 首先要对AzurePack有个基本的了解.   Azure Pack是微软的私有云方案,具有弹性. ...

  2. 关于项目中值对象Identifier的设计-领域驱动

    到现在为止做了不项目,发现每个实体都会有个相应的值对象. 先简单说一下值对象和实体之间的区别: (以下内容来着<领域驱动设计>一书) 当一个小孩画画的时候,他注意的是画笔的颜色和笔尖的粗细 ...

  3. 连接输出 如果存在在php中多次echo输出js的时候

  4. html 空链接 href="#"与href="javascript:void(0)"的区别

    #包含了一个位置信息 默认的锚是#top 也就是网页的上端 而javascript:void(0) 仅仅表示一个死链接 这就是为什么有的时候页面很长浏览链接明明是#但跳动到了页首 而javascrip ...

  5. Java基础学习总结——Java对象的序列化和反序列化

    一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存 ...

  6. OneThink-nav标签

    /* 导航列表 */ public function _nav($tag, $content){ trace($tag); trace($content); trace("end" ...

  7. Spring学习系列(二) 自动化装配Bean

    一.Spring装配-自动化装配 @Component和@ComponentScan 通过spring注解(@Component)来表明该类会作为组件类,并告知Spring要为这类创建bean,不过组 ...

  8. php实现设计模式之 解释器模式

    <?php /* * 解释器模式:给定一种语言,定义它文法的一种表示,并定义一个解释器,该解释器利用该表示来解释语言中的句子 * */ class Expression { function i ...

  9. 如何寻找“真爱”型合伙人

          曾与朋友笑侃,现在找人结婚,跟合伙开公司差不多,各自条件一一对比,细细斟酌,最后双方达成一致,才得凑成一对冤家.谁说不是呢?两种关系都实为"伙伴",开公司重" ...

  10. OData V4 系列 .net应用

    OData 学习目录 添加 OData Client Code Generator 扩展 添加OData T4生成工具 修改 T4 模板的 MetadataDocumentUri 运行Web项目,之后 ...