坤坤的最佳咖啡(线段树)

坤坤的最佳咖啡

Description

为了在课堂上保持清醒和专注,坤坤需要一些咖啡!

作为咖啡爱好者的它想知道煮一杯完美咖啡的最佳温度。事实上,它花了一段时间阅读了一些书籍。某些本书表明,咖啡应该在[Li,Ri]度之间酿造,以达到最佳口味。

坤坤认为,它要煮出完美咖啡,它选择的温度至少符合K本书的温度要求。

坤坤有一颗变化无常的心,所以它问Q个问题。在每一个问题中,考虑到它只想在[A,B]的温度准备咖啡,你能告诉它这个范围有多少可接受的整数温度吗?

Input

输入的第一行包含三个整数,n,k(1 ≤ k ≤ n ≤ 200000),q(1 ≤ q ≤ 200000),书的数量,最少要求的数量,以及询问的数量。

接下来的N行描述每本书中推荐的温度。特别地,其中的第i行包含两个整数Li和Ri(1 ≤ Li ≤ Ri ≤ 200000),说明第i本书表明最佳咖啡是在[Li,Ri]度之间酿成的。

接下来的Q行描述问题。每一条询问都包含A和B,(1 ≤ A ≤ B ≤ 200000),说明她想知道[A,B]度之间的允许的整数温度的数目。

Output

输出对于每个问题,在一行上输出一个单独的整数,表示在[A,B]之间允许的整数温度的数量。

Sample Input 1 

4 2 4
1 3
2 4
8 9
9 10
1 1
2 2
3 3
9 9

Sample Output 1

0
1
1
1
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int maxn=200010;
  7 int n,k,q;
  8 struct node{
  9     int l;
 10     int r;
 11     int val;
 12     int sum;
 13     int laz;
 14 }e[maxn<<2];
 15 void build(int l,int r,int cur)
 16 {
 17     e[cur].l=l;
 18     e[cur].r=r;
 19     e[cur].val=0;
 20     e[cur].sum=0;
 21     e[cur].laz=0;
 22     if(l==r)
 23         return;
 24     int mid=(l+r)/2;
 25     build(l,mid,cur<<1);
 26     build(mid+1,r,cur<<1|1);
 27 }
 28 void pushdown(int cur)
 29 {
 30     if(e[cur].laz!=0)
 31     {
 32         e[cur<<1].laz+=e[cur].laz;
 33         e[cur<<1|1].laz+=e[cur].laz;
 34         e[cur].laz=0;
 35     }
 36     return;
 37 }
 38 void pushup(int cur)
 39 {
 40     e[cur].sum=e[cur<<1].sum+e[cur<<1|1].sum;
 41     return;
 42 }
 43 void update(int pl,int pr,int cur)
 44 {
 45     if(pl<=e[cur].l&&e[cur].r<=pr)
 46     {
 47         e[cur].laz++;
 48         return;
 49     }
 50     int mid=(e[cur].l+e[cur].r)/2;
 51     if(pl<=mid)
 52         update(pl,pr,cur<<1);
 53     if(pr>mid)
 54         update(pl,pr,cur<<1|1);
 55 }
 56 void update1(int cur)
 57 {
 58     if(e[cur].l==e[cur].r)
 59     {
 60         if(e[cur].laz>=k)
 61             e[cur].sum=1;
 62         return;
 63     } pushdown(cur);
 64     update1(cur<<1);
 65     update1(cur<<1|1);
 66 pushup(cur);
 67 }
 68 int query(int pl,int pr,int cur)
 69 {
 70     if(pl<=e[cur].l&&e[cur].r<=pr)
 71     {
 72         return e[cur].sum;
 73     }
 74    // pushdown(cur);
 75     int ans=0;
 76     int mid=(e[cur].l+e[cur].r)/2;
 77     if(pl<=mid)
 78         ans+=query(pl,pr,cur<<1);
 79     if(pr>mid)
 80         ans+=query(pl,pr,cur<<1|1);
 81   //  pushup(cur);
 82     return ans;
 83 }
 84 int main()
 85 {
 86     scanf("%d%d%d",&n,&k,&q);
 87 
 88     build(1,200000,1);
 89     for(int i=0;i<n;i++)
 90     {
 91         int a,b;
 92         scanf("%d%d",&a,&b);
 93         update(a,b,1);
 94     }
 95     update1(1);
 96     int x,y;
 97 
 98     while(q--)
 99     {
100         scanf("%d%d",&x,&y);
101         printf("%d\n",query(x,y,1));
102     }
103 }

第二种做法:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=200100;
 5 struct node
 6 {
 7     int l,r;
 8     int val;
 9     int sum;
10 }tree[maxn<<2];
11 int n,k,q;
12 void build(int l,int r,int cur)
13 {
14     tree[cur].l=l;
15     tree[cur].r=r;
16     tree[cur].val=0;
17     tree[cur].sum=0;
18     if(r==l) return;
19     int mid=(r+l)>>1;
20     build(l,mid,cur<<1);
21     build(mid+1,r,cur<<1|1);
22 }
23 void update(int pl,int pr,int cur)
24 {
25     if(pl<=tree[cur].l&&tree[cur].r<=pr)
26     {
27         tree[cur].val++;
28         return;
29     }
30     if(pl<=tree[cur<<1].r) update(pl,pr,cur<<1);
31     if(pr>=tree[cur<<1|1].l) update(pl,pr,cur<<1|1);
32 
33 }
34 int update1(int cur)
35 {
36     if(tree[cur].l==tree[cur].r)
37     {
38         if(tree[cur].val>=k) tree[cur].sum=1;
39         return tree[cur].sum;
40     }
41     if(tree[cur].val)
42     {
43         tree[cur<<1].val+=tree[cur].val;
44         tree[cur<<1|1].val+=tree[cur].val;
45     }
46     int res=0;
47     res=update1(cur<<1);
48     res+=update1(cur<<1|1);
49     tree[cur].sum=res;
50 }
51 int query(int pl,int pr,int cur)
52 {
53     if(pl<=tree[cur].l&&tree[cur].r<=pr)
54     {
55         return tree[cur].sum;
56     }
57     int res=0;
58     if(pl<=tree[cur<<1].r) res+=query(pl,pr,cur<<1);
59     if(pr>=tree[cur<<1|1].l) res+=query(pl,pr,cur<<1|1);
60     return res;
61 }
62 int main()
63 {
64     int l,r;
65     scanf("%d%d%d",&n,&k,&q);
66     build(1,200000,1);
67     while(n--)
68     {
69         scanf("%d%d",&l,&r);
70         update(l,r,1);
71     }
72     update1(1);
73     while(q--)
74     {
75         scanf("%d%d",&l,&r);
76         printf("%d\n",query(l,r,1));
77     }
78     return 0;
79 }

第三种:

 1 #include <iostream>
 2 using namespace std;
 3 const int maxn=2e5+2;
 4 struct tree
 5 {
 6     int l,r,val;
 7     int lazy; 
 8 }e[maxn<<2];
 9 void build(int l,int r,int cur)
10 {
11     e[cur].l=l;
12     e[cur].r=r; 
13     e[cur].val=0;
14     e[cur].lazy=0;
15     if(l==r)
16         return;
17     int m=l+r>>1;
18     build(l,m,cur<<1);
19     build(m+1,r,cur<<1|1);
20 }
21 void pushdown(int cur)
22 { 
23     if(e[cur].lazy!=0)
24     {
25         e[cur<<1].val+=e[cur].lazy*(e[cur<<1].r-e[cur<<1].l+1);
26         e[cur<<1|1].val+=e[cur].lazy*(e[cur<<1|1].r-e[cur<<1|1].l+1);
27         e[cur<<1].lazy+=e[cur].lazy;
28         e[cur<<1|1].lazy+=e[cur].lazy;
29         e[cur].lazy=0;
30     }
31     return;
32 }
33 void pushup(int cur)
34 {
35     e[cur].val=e[cur<<1].val+e[cur<<1|1].val;
36     return;
37 }
38 void update(int pl,int pr,int cur)
39 {
40     if(pl<=e[cur].l&&e[cur].r<=pr)
41     {
42         e[cur].lazy++;
43         e[cur].val+=e[cur].r-e[cur].l+1;
44         return;
45     }
46     pushdown(cur);
47     int m=e[cur].l+e[cur].r>>1;
48     if(pl<=m)update(pl,pr,cur<<1);
49     if(pr>m)update(pl,pr,cur<<1|1);
50    pushup(cur);
51     return;
52 } 
53 int query(int id,int cur)
54 {
55     if(e[cur].l==e[cur].r)
56     {
57         return e[cur].val;
58     }
59     pushdown(cur);
60     int m=e[cur].l+e[cur].r>>1;
61     if(id<=m) query(id,cur<<1);
62     else query(id,cur<<1|1);
63 }
64 int main()
65 {
66     int n,k,q;
67     scanf("%d%d%d",&n,&k,&q);
68     build(1,maxn,1);
69     for(int i=0;i<n;i++)
70     {
71         int a,b;
72         scanf("%d%d",&a,&b);
73         update(a,b,1);
74     } 
75     long long  sum[maxn];
76     sum[0]=0;
77     for(int i=1;i<maxn-1;i++)
78     {    
79         int ans=query(i,1);
80         if(ans>=k)
81             ans=1;
82         else
83             ans=0;
84         sum[i]=sum[i-1]+ans;    
85     }
86     for(int i=0;i<q;i++)
87     {
88         int a,b;
89         scanf("%d%d",&a,&b);
90         
91         printf("%lld\n",sum[b]-sum[a-1]);
92     }
93     return 0;
94 }

 

 
posted @ 2018-08-29 09:41  *starry*  阅读(159)  评论(0编辑  收藏  举报