1 5 5 1 2 3 5 6 1 2 3 4 5
4 4 4 4 7
出题人的解题思路:
先排下序,然后记录每个数字出现的位置。 对于询问q,如果q不存在直接输出q 如果q存在。 假设q所在位置为pos,那么二分[pos, n]这个区间,二分判断的依据是如果mid - p == num[mid] - num[p] 那么left = mid+1, 否则right = mid-1 时间复杂度O(m * lgn)因为每个任务执行的时间是不同的,而且数据大小不大,所以可以采用标记法来记录已经用于执行任务的时间,那么未被标记的就是空闲的时间,而每次询问只需二分空闲的时间,大于等于当前额外任务时间的空闲时间即为所求的结果
#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 using namespace std; const int N = 200005; const int inf = 1000000000; const int mod = 258280327; bool s[N]; int c[N]; int main() { int t,n,m,i,x,Max,k; scanf("%d",&t); while(t--) { Max=0; memset(s,false,sizeof(s)); scanf("%d%d",&n,&m); for(i=0;i<n;i++) { scanf("%d",&x); s[x]=true; Max=Max>x?Max:x; } for(i=1,k=0;i<=Max;i++) if(!s[i]) c[k++]=i; c[k++]=Max+1; for(i=0;i<m;i++) { scanf("%d",&x); if(x>Max+1) printf("%d\n",x); else printf("%d\n",c[lower_bound(c,c+k,x)-c]); } } return 0; }
当然,这里不用二分也是可以的,数据比较小,把所有的记录一遍,最后就是O(1)的询问了
for(i=max;i>0;i--) { if(t[i]==1) t[i]=t[i+1]; else t[i]=i; }菜鸟成长记