Negative and Positive (NP)
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3330 Accepted Submission(s): 896
Problem Description
When given an array
(a0,a1,a2,⋯an−1)
and an integer
K
, you are expected to judge whether there is a pair
(i,j)(0≤i≤j<n)
which makes that
NP−sum(i,j)
equals to
K
true. Here
NP−sum(i,j)=ai−ai+1+ai+2+⋯+(−1)j−iaj
Input
Multi test cases. In the first line of the input file there is an integer
T
indicates the number of test cases.
In the next 2∗T lines, it will list the data for each test case.
Each case occupies two lines, the first line contain two integers n and K which are mentioned above.
The second line contain (a0,a1,a2,⋯an−1) separated by exact one space.
[Technical Specification]
All input items are integers.
0<T≤25,1≤n≤1000000,−1000000000≤ai≤1000000000,−1000000000≤K≤1000000000
In the next 2∗T lines, it will list the data for each test case.
Each case occupies two lines, the first line contain two integers n and K which are mentioned above.
The second line contain (a0,a1,a2,⋯an−1) separated by exact one space.
[Technical Specification]
All input items are integers.
0<T≤25,1≤n≤1000000,−1000000000≤ai≤1000000000,−1000000000≤K≤1000000000
Output
For each case,the output should occupies exactly one line. The output format is Case #id: ans, here id is the data number starting from 1; ans is “Yes.” or “No.” (without quote) according to whether you can find
(i,j)
which makes
PN−sum(i,j)
equals to
K
.
See the sample for more details.
See the sample for more details.
Sample Input
2 1 1 1 2 1 -1 0
Sample Output
Case #1: Yes. Case #2: No.HintIf input is huge, fast IO method is recommended.
NP−sum(i,j)=ai−ai+1+ai+2+⋯+(−1)j−iaj等于k
思路:我们先维护两个前缀和,第一个是sum[i]=a[1]-a[2]+a[3]+,,,+(-1)的(i-1)次方*a[i]
第二个就等于-sum[i],就是说奇数项为负~
然后我们维护两个hash,一个保存sum[i],一个保存-sum[i]
然后枚举区间的左端点,因为sum[i]-sum[j]=k
因为区间[i,j]里,第一项a[i]必须为正。
所以如果当前枚举的i点下标为奇数,那么我们就从第一个hash里找有没有一个值等于sum[i]-k
反之如果当前枚举的i点下标为偶数,那么我们就从第二个hash里找有没有一个值等于-sum[i]-k(也就是把整个-sum[i]-k=-sum[j])
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 1000050
long long a[N],sum[N];
struct Hashmap
{
int head[N],next[N],cnt;
long long state[N];
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
int check(long long val)
{
int h=(val%N+N)%N;
for(int i=head[h];i!=-1;i=next[i])
if(state[i]==val) return 1;
return 0;
}
int Insert(long long val)
{
int h=(val%N+N)%N;
for(int i=head[h];i!=-1;i=next[i])
if(val==state[i])
return 1;
state[cnt]=val;
next[cnt]=head[h];
head[h]=cnt++;
return 0;
}
}H1,H2;
int main()
{
int T;
int n,k,t=1;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
long long sum=0;
H1.init();H2.init();
H1.Insert(0);H2.Insert(0);
int flag=0;
for(int i=n;i>=1&&!flag;i--)
{
if(i&1) sum+=a[i];
else sum-=a[i];
if(i&1)
{
if(H1.check(sum-k))
flag=1;
}
else
{
if(H2.check(-sum-k))
flag=1;
}
H1.Insert(sum);
H2.Insert(-sum);
}
printf("Case #%d: ",t++);
if(flag) printf("Yes.\n");
else printf("No.\n");
}
return 0;
}
NP−sum(i,j)=ai−ai+1+ai+2+⋯+(−1)j−iaj