超时代码:
#include <bits/stdc++.h>
using namespace std;
int n, m, k, Index[100005];
struct Plan{
int t, c;
}p[100005];
int main(int argc, char** argv) {
scanf("%d %d %d", &n, &m, &k);
int j = 0, q;
for(int i = 0; i < n; ++i){
scanf("%d %d", &p[i].t, &p[i].c);
int cur = p[i].t;
while(j<=cur) Index[j++] = i; //有序,向后映射最近避免有重复
}
for(int i = 0; i < m; ++i){ //有序但不能保证紧接着
scanf("%d", &q);
int start = q + k, cnt = 0;
for(int j = Index[start]; j < n; ++j){
if(p[j].t - start > p[j].c - 1) continue; //防止后面有更宽松的要求
else ++cnt;
}
printf("%d\n", cnt);
}
return 0;
}
AC代码:
已知t,查询q,则区间:q+k<=t<=q+k+c-1 --> t-k-c+1<=q<=t-k
利用差分与前缀和,区间累加影响,左右段抵消
#include <bits/stdc++.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
const int N = 200005;
int n, m, k, s[N], t, c;
int main(int argc, char** argv) {
scanf("%d %d %d", &n, &m, &k);
for(int i = 0; i < n; ++i){
scanf("%d %d", &t, &c);
++s[max(1, t-k-c+1)]; //左边界从1开始, s[0]动态规划起点
--s[max(1, t-k+1)]; //消除区域后影响
}
for(int i = 1; i <= N; ++i) s[i] += s[i-1]; //前缀和累加影响
int q;
for(int i = 0; i < m; ++i){
scanf("%d", &q);
printf("%d\n", s[q]);
}
return 0;
}