Lpl and Energy-saving Lamps ( 线段树 求第一个小于等于k的数)

传送门:https://vjudge.net/contest/349835#problem/A

       题意:长度为n的序列代表每个房间的灯泡需求,k为每个月新获得的灯泡,从左往右找当手头的灯泡>=房间的需求时为房间更换灯泡,若没有房间满足则留着下一个月用,q次询问,回答在第i个月装修了多少个房间,手头上的灯泡还剩多少。

       思路:线段树维护区间最小值月份数可达1e5,预处理每一个月份的答案,每个月份用logn的时间从左往右找可以装修的房间,找到则维护答案并单点更新叶子结点为inf代表去除该结点,记录ans数组最后输出就行。

AC代码:

 1 #include<iostream>
 2 #include<math.h>
 3 const int maxn=1e5+50;
 4 const int inf=0X3f3f3f3f;
 5 using namespace std;
 6 
 7 int n,m,q;
 8 int a[4*maxn],A[maxn],que[maxn];
 9 
10 struct node{
11     int num;
12     int res;
13 }ans[maxn];
14 
15 void pushup(int rt){
16     a[rt]=min(a[rt<<1],a[rt<<1|1]);
17 }
18 
19 void build(int l,int r,int rt){
20     if(l==r){
21         a[rt]=A[l];
22         return;
23     }
24     int m=l+r>>1;
25     build(l,m,rt<<1);
26     build(m+1,r,rt<<1|1);
27     pushup(rt);
28 }
29 
30 void updata(int p,int x,int l,int r,int rt){
31     if(l==r){
32         a[rt]=x;
33         return;
34     }
35     int m=l+r>>1;
36     if(p<=m)
37         updata(p,x,l,m,rt<<1);
38     else
39         updata(p,x,m+1,r,rt<<1|1);
40     pushup(rt);
41 }
42 
43 int query(int x,int l,int r,int rt){//从左到右查找第一个大于x的叶子节点位置
44     if(a[rt]>x){//代表没有房间符合
45         return 0;
46     }
47     int m=l+r>>1;
48     if(l==r) return l;//注意返回的不是rt 是 l
49     else{
50         if(a[rt<<1]<=x)        query(x,l,m,rt<<1);
51         else if(a[rt<<1|1]<=x) query(x,m+1,r,rt<<1|1);
52     }
53 }
54 
55 int main()
56 {
57     cin>>n>>m;
58     for(int i=1;i<=n;i++)
59         cin>>A[i];
60     cin>>q;
61     for(int i=1;i<=q;i++){
62         cin>>que[i];
63     }
64     build(1,n,1);
65     int nnum=0,nres=0;
66     for(int i=1;i<=1e5+10;i++){
67         if(nnum>=n){
68             ans[i].num=nnum;
69             ans[i].res=nres;
70             continue;
71         }
72         nres+=m;
73         while(nres){
74             int index=query(nres,1,n,1);
75             if(index==0) break;//表示现在没有可以用的房间了
76             nnum++;nres-=A[index];
77             updata(index,inf,1,n,1);
78         }
79         ans[i].num=nnum;
80         ans[i].res=nres;
81     }
82     for(int i=1;i<=q;i++){
83         cout<<ans[que[i]].num<<" "<<ans[que[i]].res<<'\n';
84     }
85     return 0;
86 }

猜你喜欢

转载自www.cnblogs.com/qq2210446939/p/12146543.html