NOJ——1649Find Sum(二分查找)
-
[1649] Find Sum
- 时间限制: 1000 ms 内存限制: 65535 K
- 问题描述
-
This problem is really boring.
You are given a number sequence S which contain n integers and m queries, each time i will give your two integers id1 and id2, you need to tell me whether i can get S[id1] + S[id2] from the n integers.
- 输入
-
Input starts with an integer T(T <= 5) denoting the number of test cases.
For each test case, n(1 <= n <= 100000, 1 <= m <= 10000) are given, and the second line contains n integers, each of them is larger then 0 and no larger than 10^11.
Next m lines, each line contains two integers id1 and id2(1 <= id1, id2 <= n). - 输出
-
For each case, first print the case number.
For each query, print “Yes” if i can get S[id1] + S[id2] from S, otherwise print “No”(without the quote). - 样例输入
-
1 5 3 3 4 2 1 3 1 2 3 4 4 5
- 样例输出
-
Case 1: No Yes Yes
会了二分查找之后这类题型做起来简直爽翻。科科~果然二分一般都是最先接触的算法吗。。。注意一点就是题目中给的数据或者说中间数据会超出int范围,第一次交RE了,改成__int64就AC了
代码:
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; bool bi_search(const __int64 list[],const __int64 &len,const __int64 &goal) { __int64 l=0,r=len-1; while (l<=r) { __int64 mid=(l+r)>>1; if(list[mid]==goal) return true; else if(list[mid]<goal) { l=mid+1; } else { r=mid-1; } } return false; } int main(void) { int t,q; scanf("%d",&t); for (q=1; q<=t; q++) { __int64 n,m,i,d1,d2; scanf("%I64d%I64d",&n,&m); __int64 *list=new __int64[n];//用来放初始值 __int64 *tlist=new __int64[n];//用来保存sort之后的有序序列,不然无法二分 for (i=0; i<n; i++) { scanf("%I64d",&list[i]); tlist[i]=list[i]; } sort(tlist,tlist+n); printf("Case %d:\n",q); for (i=0; i<m; i++) { scanf("%I64d %I64d",&d1,&d2); if(bi_search(tlist,n,list[d1-1]+list[d2-1])) printf("Yes\n"); else printf("No\n"); } delete []list; delete []tlist; } return 0; }