1. 程式人生 > >Karen and Coffee 思維+字首和

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