Karen and Coffee 差分+前缀
题目链接:传送门
题意:给你n个区间,一个K值和q次询问,输出区间中重复次数>=k的点的个数。
做法:这道题有一个巧妙做法,输入区间(l,r)时,将数组的下标为 l 的 +1,r+1 的 -1
(假设数组为 coffe ,初始化为0,即 coffe[l]++,coffe[r+1]--)。 然后在求一个前缀和,数组对应的值就是该点出现的次数。
为什么呢是这样的呢?点和区间的关系:包含(里面),不包含(前面,后面)
前面:区间所对应的 coff[l]+coffe[r+1]=0,不会对该点的值造成影响。
里面:该点被几个区间包含,就会有几个coffe[l]对其造成影响。
因为有多次询问,对coffe数组再进行一个条件前缀和(coffe[i]=coffe[i-1]+(coffe[i]>=k))
查询时输出 coffe[r]-coffe[l-1]即可。
代码:
///#include<bits/stdc++.h>
///#include<unordered_map>
///#include<unordered_set>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#include<new>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double E=2.718281828459;
int main()
{
int n,k,q,l,r,coffe[200005];
memset(coffe,0,sizeof(coffe));
scanf("%d %d %d",&n,&k,&q);
for(int i=1; i<=n; i++)
{
scanf("%d %d",&l,&r);
coffe[l]++;
coffe[r+1]--;
}
for(int i=1; i<=200000; i++)
coffe[i]=coffe[i]+coffe[i-1];
for(int i=1; i<=200000; i++)
coffe[i]=coffe[i-1]+(coffe[i]>=k);
while(q--)
{
scanf("%d %d",&l,&r);
printf("%d\n",coffe[r]-coffe[l-1]);
}
return 0;
}