2 1 1 1 2 1 -1 0
Case #1: Yes. Case #2: No.HintIf input is huge, fast IO method is recommended.
/************************************************************************/
附上该题对应的中文题
给定一个数组(a0,a1,a2,⋯an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP−sum(i,j) 刚好为K。这里。
多组测试数据。在文件的第一行给出一个T,表示有T组数据。 在接下来的2∗T行里,将会给出每一组数据。 每一组数据占两行,第一行包含n和K。 第二行包含(a0,a1,a2,⋯an−1)以一个空格分开。 [参数说明] 所有输入均为整数。 0<T≤25,1≤n≤1000000,−1000000000≤ai≤1000000000,−1000000000≤K≤1000000000
对于每一个数据,输出占一行,输出格式是Case #id: ans,这儿id是数据编号,从1开始,ans是根据是否找到满足的二元组而定为“Yes.” 或 “No.” (不包含引号) 看样例可以获得更多的信息。
2 1 1 1 2 1 -1 0
Case #1: Yes. Case #2: No.
如果数据比较多,建议使用快速读入。
出题人的解题思路:
维护前缀和sum[i]=a[0]-a[1]+a[2]-a[3]+…+(-1)^i*a[i] 枚举结尾i,然后在hash表中查询是否存在sum[i]-K的值。 如果当前i为奇数,则将sum[i]插入到hash表中。 上面考虑的是从i为偶数为开头的情况。 然后再考虑以奇数开头的情况,按照上述方法再做一次即可。 不同的是这次要维护的前缀和是sum[i]=-(a[0]-a[1]+a[2]-a[3]+…+(-1)^i*a[i]) I为偶数的时候将sum[i]插入到hash表。 总复杂度o(n)该题的解法,出题人讲得很明确,利用哈希函数,我们将求得的sum[i](前i项的NP-sum值)求出来放入哈希表中,遍历一遍即可判断是否存在一个二元组满足条件
我要提的一点是题目的读入优化,因为题目的数据比较多,普通的输入耗的时间也会比较长,容易TLE,所以此题需用到读入优化,详情可点击链接
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 #define ll __int64 using namespace std; const int N = 1000005; const int inf = 1000000000; const int mod = 1000005; struct node { int to; ll v; }e[N]; int s[N],h[N],p; void add(ll x) { e[p].v=x; x=abs(x)%N; e[p].to=h[x]; h[x]=p++; } bool check(ll x) { int k=abs(x)%N; for(int i=h[k];i+1;i=e[i].to) if(e[i].v==x) return true; return false; } int get_val(int &ret) { int sgn=1; char c; while(((c=getchar())<'0'||c>'9')&&c!='-'); if(c=='-') sgn=-1,ret=0; else ret=c-'0'; while((c=getchar())>='0'&&c<='9') ret=ret*10+c-'0'; ret*=sgn; } int main() { int t,n,k,i,j=1; ll sum; get_val(t); while(t--) { sum=0;p=0; memset(h,-1,sizeof(h)); get_val(n); get_val(k); for(i=0;i<n;i++) get_val(s[n-i-1]); add(0); printf("Case #%d: ",j++); for(i=0;i<n;i++) { sum+=(i&1)?-s[i]:s[i]; add(sum); if(i&1) { if(check(sum+k)) { puts("Yes."); break; } } else if(check(sum-k)) { puts("Yes."); break; } } if(i>=n) puts("No."); } return 0; }菜鸟成长记