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;
}

猜你喜欢

转载自blog.csdn.net/qq_42211531/article/details/84066671