Question link:https://nanti.jisuanke.com/t/30996
The translation of question:(please reference Google translation)
Question meaning:balalbala一大顿之后主干意思就是,有n个房子,里面有着不用的白炽灯,为了省电,要把这些
白炽灯换成节能灯,每个月给你m个节能灯,然后你从头开始找,找到需要换的数量小于你手里节能灯的数量就把
这个房间的灯全给换掉,直到走完全部房间,或者你手里没有灯为止,然后等下个月再来m个灯。(月数m<1e5,刚开始
以为只有12个月。。。)然后问你某个月完成了几个房间,手里剩下多少几个灯。
The solution of the question : Segment Tree ,creat a table(打表是这么写?)
A few days ago,I have written an article of segment tree.Now it can come in handy.
FIrst of all ,we recall that article together .
The blog link of segment tree : https://blog.csdn.net/weixin_40532377/article/details/82784855
The sement tree is the key that you can accepted this question,if you don't know what's segment tree,you kan
view my blog of it, otherwise this quetion will make you confused.
I will explain this question with my code in detail
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int INF=maxn;
struct node{
int l;
int r;
int min;
}room[maxn*4]; //建树具体见上一个blog
int n,m;
struct s{
int save; //这个月剩下的灯泡
int already; //这个月完成的房间数
}month[maxn];
void build(int l,int r,int k){
room[k].l=l;
room[k].r=r;
if(l==r) return ;
int mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
}
void update(int i,int k,int val){
if(room[k].l==i&&room[k].r==i){
room[k].min=val;
return ;
}
int mid=(room[k].l+room[k].r)/2;
if(i<=mid) update(i,k*2,val);
else update(i,k*2+1,val);
room[k].min=min(room[k*2].min,room[k*2+1].min);
}
void search(int k,int i){ //这个地方就要自己好好想想怎么实现了
if(month[i].save<room[k].min) return; //如果房间的灯泡没有比手里少的 直接return
if(room[k].l==room[k].r){ //找到了某个可以换灯泡的房间
month[i].already++;
month[i].save-=room[k].min;
room[k].min=INF; //将换完的数目改成INF
return;
}
search(k*2,i);
search(k*2+1,i);
room[k].min=min(room[k*2].min,room[k*2+1].min); //更新每一层的最小值
}
int main()
{
int temp;
memset(month,0,sizeof(month));
month[0].save=month[0].already=month[1].save=month[1].already=0;
cin>>n>>m;
build(1,n,1);
for(int i=1;i<=n;i++){
scanf("%d",&temp);
update(i,1,temp);
}
int i;
for(i=1;i<maxn;i++){
month[i].already=month[i-1].already; //每个月刚开始和上个月完成的房间相同
if(month[i-1].already<n){
month[i].save=month[i-1].save+m; //每个月给你m个灯泡
search(1,i);
}
else break;
}
for(;i<maxn;i++){
month[i].save=month[i-1].save;
month[i].already=month[i-1].already; //全安完了把剩下的表打上
}
int t,q;
cin>>t;
while(t--){
scanf("%d",&q);
printf("%d %d\n",month[q].already,month[q].save);
}
return 0;
}