1. 程式人生 > >ZZNU-OJ-2098 : Drink coffee【線段樹合並區間或者 差分 + 二分索引樹】

ZZNU-OJ-2098 : Drink coffee【線段樹合並區間或者 差分 + 二分索引樹】

因此 愛好 opened 包括 pri 閱讀 hid 大致 val

 1 2098 : Drink coffee
 2 時間限制:1 Sec 內存限制:256 MiB
 3 提交:40 答案正確:14
 4 
 5 提交 狀態 討論區
 6 
 7 題目描述
 8 為了在上課時保持清醒,凱倫需要一些咖啡。咖啡愛好者凱倫想知道最佳的溫度來沖煮完美的咖啡。因此,她花了一些時間閱讀幾本食譜,其中包括廣受好評的“咖啡的藝術”。
 9 她知道有n個食譜,其中第i個食譜建議應當在li和ri度之間沖煮以達到最佳的味道。凱倫認為如果至少k個食譜推薦某個溫度,那麽那個溫度是可以接受的。
10 凱倫的性格比較多變,因此她會問q個問題,對於每一個問題,她會給出一個溫度區間[a,b],你要告訴她有多少可接受的整數溫度在這個範圍內。
11 12 輸入 13 第一行輸入包含三個整數,n,k(1≤k≤n≤200000)和q(1≤q≤200000),如題中所描述。 14 接下來n行描述每一個食譜,具體來說,其中的第i行包含兩個整數li和ri(1≤li≤ri≤200000),描述第i個食譜建議咖啡在li和ri度之間進行沖煮(包括端值)。 15 接下來q行為q個詢問。這些行中的每一行都包含a和b,(1≤a≤b≤200000),表示她想知道a和b度之間的可接受的整數溫度的數量,包括a和b。 16 輸出 17 對於每個詢問,輸出一個答案。 18 19 樣例輸入 20 復制 21 3 2 4
22 91 94 23 92 97 24 97 99 25 92 94 26 93 97 27 95 96 28 90 100 29 樣例輸出 30 復制 31 3 32 3 33 0 34 4 35 提示

大致思路:

  差分 + 二分索引樹。

技術分享圖片
 1 using namespace std;
 2 #define inf 0x3f3f3f3f
 3 const double pi=acos(-1.0);
 4 #define ll long long
 5 #define N 200008
 6 #define lson root<<1
 7
#define rson root<<1|1 8 int a[N];//統計個數 9 int bit[N]; 10 int lowbit(int x){ 11 return x & -x; //或者可以return x&(x-1); 12 } 13 int sum(int x){ //計算前x項的和 14 int s=0; 15 while(x>0){ 16 s+=bit[x]; 17 x-=lowbit(x); 18 } 19 return s; 20 } 21 //add(),每次添加的範圍至少要覆蓋全部的範圍! 22 void add(int x,int val,int n){ //在x位置上加上val, 更改二叉索引樹上的和 ,只能這麽添加數 23 while(x<=n){ 24 bit[x]+=val; 25 x+=lowbit(x); 26 } 27 } 28 int main(){ 29 30 int n,k,q; //差分+樹狀數組 31 while(scanf("%d%d%d",&n,&k,&q)!=EOF){ 32 memset(a,0,sizeof(a)); 33 memset(bit,0,sizeof(bit)); 34 35 int li,ri,maxn=-1; 36 for(int i=1;i<=n;i++){ 37 scanf("%d%d",&li,&ri); 38 a[li]++,a[ri+1]--; 39 maxn=max(maxn,ri); 40 } 41 42 for(int i=1;i<=maxn+1;i++){ 43 a[i]+=a[i-1]; 44 if(a[i]>=k)add(i,1,N-8); 45 } 46 47 while(q--){ 48 scanf("%d%d",&li,&ri); 49 printf("%d\n",sum(ri)-sum(li-1)); 50 } 51 52 } 53 54 return 0; 55 }
View Code(頭文件私奔啦!!)

ZZNU-OJ-2098 : Drink coffee【線段樹合並區間或者 差分 + 二分索引樹】