坤坤的最佳咖啡(线段树)
坤坤的最佳咖啡
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 }