ACM-ICPC 2018 南京赛区网络预赛 G. Lpl and Energy-saving Lamps 经典线段树

版权声明:本博客内容基本为原创,如有问题欢迎联系,转载请注明出处 https://blog.csdn.net/qq_41955236/article/details/82428888

During tea-drinking, princess, amongst other things, asked why has such a good-natured and cute Dragon imprisoned Lpl in the Castle? Dragon smiled enigmatically and answered that it is a big secret. After a pause, Dragon added:

— We have a contract. A rental agreement. He always works all day long. He likes silence. Besides that, there are many more advantages of living here in the Castle. Say, it is easy to justify a missed call: a phone ring can't reach the other side of the Castle from where the phone has been left. So, the imprisonment is just a tale. Actually, he thinks about everything. He is smart. For instance, he started replacing incandescent lamps with energy-saving lamps in the whole Castle...

Lpl chose a model of energy-saving lamps and started the replacement as described below. He numbered all rooms in the Castle and counted how many lamps in each room he needs to replace.

At the beginning of each month, Lpl buys mmm energy-saving lamps and replaces lamps in rooms according to his list. He starts from the first room in his list. If the lamps in this room are not replaced yet and Lpl has enough energy-saving lamps to replace all lamps, then he replaces all ones and takes the room out from the list. Otherwise, he'll just skip it and check the next room in his list. This process repeats until he has no energy-saving lamps or he has checked all rooms in his list. If he still has some energy-saving lamps after he has checked all rooms in his list, he'll save the rest of energy-saving lamps for the next month.

As soon as all the work is done, he ceases buying new lamps. They are very high quality and have a very long-life cycle.

Your task is for a given number of month and descriptions of rooms to compute in how many rooms the old lamps will be replaced with energy-saving ones and how many energy-saving lamps will remain by the end of each month.

Input

Each input will consist of a single test case.

The first line contains integers nnn and m(1≤n≤100000,1≤m≤100)m (1 \le n \le 100000, 1 \le m \le 100)m(1≤n≤100000,1≤m≤100) — the number of rooms in the Castle and the number of energy-saving lamps, which Lpl buys monthly.

The second line contains nnn integers k1,k2,...,knk_1, k_2, ..., k_nk1​,k2​,...,kn​
(1≤kj≤10000,j=1,2,...,n)(1 \le k_j \le 10000, j = 1, 2, ..., n)(1≤kj​≤10000,j=1,2,...,n) — the number of lamps in the rooms of the Castle. The number in position jjj is the number of lamps in jjj-th room. Room numbers are given in accordance with Lpl's list.

The third line contains one integer q(1≤q≤100000)q (1 \le q \le 100000)q(1≤q≤100000) — the number of queries.

The fourth line contains qqq integers d1,d2,...,dqd_1, d_2, ..., d_qd1​,d2​,...,dq​
(1≤dp≤100000,p=1,2,...,q)(1 \le d_p \le 100000, p = 1, 2, ..., q)(1≤dp​≤100000,p=1,2,...,q) — numbers of months, in which queries are formed.

Months are numbered starting with 111; at the beginning of the first month Lpl buys the first m energy-saving lamps.

Output

Print qqq lines.

Line ppp contains two integers — the number of rooms, in which all old lamps are replaced already, and the number of remaining energy-saving lamps by the end of dpd_pdp​ month.

Hint

Explanation for the sample:

In the first month, he bought 444 energy-saving lamps and he replaced the first room in his list and remove it. And then he had 111 energy-saving lamps and skipped all rooms next. So, the answer for the first month is 1,1−−−−−−11,1------11,1−−−−−−1 room's lamps were replaced already, 111 energy-saving lamp remain.

样例输入

5 4
3 10 5 2 7
10
5 1 4 8 7 2 3 6 4 7

样例输出

4 0
1 1
3 6
5 1
5 1
2 0
3 2
4 4
3 6
5 1

       据机房里的大神说这道题的题目是又臭又长,然而我们队根本没看这道题。。。其实这道题并不是很难,但是比赛的时候因为效率太低,前面的水题所以没有很快做出来导致这里拖了后腿。心塞了,看来还是有很长的一段路要走啊。。

题意:

       好吧啰嗦完了开始讲题意,有个人有n个房间的灯泡要换,他每个月可以拿到m个新的灯泡,每次拿到新灯泡后他都会按顺序从房间1走到房间n看这里是不是需要换,先碰到能换的就先换,用掉了这个月就不会增加了,如果所有n个房间都换完了接下来的月份里都不会再买新的了(即答案就不会再变化了)。有q个询问,每个询问都有一个月份x,问,到这个月的时候已经换了几个房间的灯泡以及生下来还有几个灯泡。

       模一下样例吧,第一个月的时候拿到了4个,去到第一个房间发现可以换就换了只剩下1个,再走2,3,4,5的时候都不能换了,第二个月又拿到4个有5个,顺序下来发现第三个房间可以换就换,剩下0个,之后就不能换了,以此类推

做法:

       题目理解了之后其实很容易发现是个线段树吧,而且还是个很裸的线段树,最多只是在询问完的更新答案这里稍微加了一点小技巧,但是以前也碰到过类似的题目。线段树中保存的以其为根的树的最小值,每次询问的时候优先向左边询问。每次更新要用while,不然会有一个月可能能换多个房间的情况。

       更新之后的答案变成一个无穷大,这样查询最小值的时候就不会再更新到了。每次query之前看看1号中的最小值(也就是当下剩下的所有房间的最小值)有没有小于灯泡数,小小的剪枝吧,还有可以先离线预处理之后再直接输出答案。

       可能是听了答案所以觉得比较简单,唉多多练吧。


#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn=100005;
const int inf=0x3f3f3f3f;
typedef pair<int,int> pii;
struct node{
    int minn;
}e[maxn<<2];
int n,m,aim[maxn],q,flag;
pii ans[maxn];
void build(int l,int r,int rt){
    if(l==r){
        e[rt].minn=aim[l];
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,lson);
    build(mid+1,r,rson);
    e[rt].minn=min(e[lson].minn,e[rson].minn);
}
int query(int l,int r,int now,int rt){
    if(l==r){
        e[rt].minn=inf;
        return aim[l];
    }
    int mid=(l+r)/2,ans;
    if(e[lson].minn<=now) ans=query(l,mid,now,lson);
    else ans=query(mid+1,r,now,rson);
    e[rt].minn=min(e[lson].minn,e[rson].minn);
    return ans;
}
int main(){

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&aim[i]);
    }
    build(1,n,1);
    for(int i=1,now=0,cnt=0;i<=100000;i++){
        if(now==n) {
            ans[i]=ans[i-1];
            continue;
        }
        cnt+=m;
        if(e[1].minn>cnt){
            ans[i]={now,cnt};
            continue;
        }
        else {
            while(e[1].minn<=cnt){
                int aim=query(1,n,cnt,1);
                cnt-=aim;
                now++;
            }
            ans[i]={now,cnt};
        }
    }
    scanf("%d",&q);
    while(q--){
        int x;
        scanf("%d",&x);
        printf("%d %d\n",ans[x].first,ans[x].second);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/82428888
今日推荐