ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【2022 杭电多校】第五场 1012 Buy Figurines 【模拟】

2022-08-03 10:32:31  阅读:145  来源: 互联网

标签:杭电多校 Buy return int 第五场 mid st type id


链接

https://acm.hdu.edu.cn/showproblem.php?pid=7196

思路

  1. 读题后发现,由于每个人的到达时间不同,且可以唯一确定加入的队伍,所以每个人选择加入的队伍是确定的
    那么只需要(按事件发生的时间顺序)模拟即可,使用优先队列

定义三元组<time,type,id> 把所有入队、出队操作看成操作序列,按照发生的时间先后排序;type用来标识入队还是出队,先出再入;id表示人或者队伍的编号

注意优先队列默认是按优先级从大到小的顺序排列,我为了让数值小的排在前面,在这里重载小于号的函数内部写大于,表示值大的反而优先级低

struct node{
    ll t;
    int type;
    int id;
    bool operator <(const node& b)const{
        if(t!=b.t) return t>b.t;
        else if(type!=b.type) return type>b.type;
        else{
            if(type==1) return a[type].st>a[b.type].st;
            else return id>b.id;
        }
    }
};
priority_queue<node>op;
  1. 模拟的同时需要查询当前人数最少的队伍,需要借助查询时间<O(n)的数据结构,使用set或者线段树等等

线段树:
再开一个数据实时记录人数,并用线段树维护区间最小值,需要查找最小值对应的编号时再写个二分就行

int l=1,r=m,mid,ind;
   while(l<=r){
   mid=(l+r)>>1;
   ll vl=query(l,mid,1,m,1),vr=query(mid+1,r,1,m,1);
   if(vl<=vr){
       r=mid;
   }
   else if(vl>vr){
       l=mid+1;
   }
   if(l==r){
       ind=l;
       break;
   }
}

set:
存储<队伍人数,队伍id>,按照队伍人数降序顺序排
还需要记录每个人对应的队伍

struct Queue{
    int num;
    int id;
    bool operator < (const Queue &aa) const{
        if(num!=aa.num) return num<aa.num;
        else return id<aa.id;
    }
}q[N];
set<Queue>st;

code

线段树:

#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int N = 2e5+10;
int T,n,m;
struct peo{
    int st;
    int len;
    int id;
    bool operator < (const peo &aa) const{
        return st<aa.st;
    }
}a[N];
ll wait[N],tim[N];

struct node{
    ll t;
    int type;
    int id;
    bool operator >(const node& b)const{
        if(t!=b.t) return t>b.t;
        else if(type!=b.type) return type>b.type;
        else{
            if(type==1) return a[type].st>a[b.type].st;
            else return id>b.id;
        }
    }
};
priority_queue<node,vector<node>,greater<node> >q;

struct SegTree{
    ll v;
    ll lazy;
}t[N<<2];

void push_up(int rt){
    t[rt].v=min(t[rt*2].v,t[rt*2+1].v);
}

void build(int l,int r,int rt){
    t[rt].lazy=0;
    if(l==r){
        t[rt].v=wait[l];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt*2);
    build(mid+1,r,rt*2+1);
    push_up(rt);
}

void upd(int L,int R,int l,int r,int rt,ll v){
    if(l>R||r<L||l>r) return;
    if(l==r){
        t[rt].v=v;
        return;
    }
    int mid=(l+r)>>1;
    upd(L,R,l,mid,rt*2,v);
    upd(L,R,mid+1,r,rt*2+1,v);
    push_up(rt);
}

ll query(int L,int R,int l,int r,int rt){
    if(L>r||R<l||l>r) return 1e18;
    if(L<=l&&r<=R){
        return t[rt].v;
    }
    int mid=(l+r)>>1;
    return min(query(L,R,l,mid,rt*2),query(L,R,mid+1,r,rt*2+1));
}

int main(){
    int T; cin>>T;
    while(T--){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].st,&a[i].len);
            a[i].id=i;
            q.push({a[i].st,2,i});  //st_time
        }

        for(int i=1;i<=m;i++){
            wait[i]=0;
            tim[i]=0;
        }
        build(1,m,1);
        while(!q.empty()){   //<time,type,id>
            auto now=q.top();
            q.pop();
            if(now.type==1){
                wait[now.id]--;
                upd(now.id,now.id,1,m,1,wait[now.id]);
            }
            else{
                int l=1,r=m,mid,ind;
                while(l<=r){
                    mid=(l+r)>>1;
                    ll vl=query(l,mid,1,m,1),vr=query(mid+1,r,1,m,1);
                    if(vl<=vr){
                        r=mid;
                    }
                    else if(vl>vr){
                        l=mid+1;
                    }
                    if(l==r){
                        ind=l;
                        break;
                    }
                }

                if(tim[ind]<a[now.id].st) tim[ind]=a[now.id].st;
                tim[ind]+=a[now.id].len;
                q.push(node{tim[ind],1,ind});
                wait[ind]++;
                upd(ind,ind,1,m,1,wait[ind]);              
            }
        }   
        ll ans=0;
        for(int i=1;i<=m;i++){
            ans=max(ans,tim[i]);
        }
        printf("%lld\n",ans);
    }

    system("pause");
    return 0;
}

set:

#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int N = 2e5+10;
int T,n,m;
struct peo{
    int st;
    int len;
    int id;
}a[N];
ll tim[N];  //总时间
int q_select[N];  //编号为i的人对应的队列(是确定的)

struct node{
    ll t;
    int type;
    int id;
    bool operator <(const node& b)const{
        if(t!=b.t) return t>b.t;
        else if(type!=b.type) return type>b.type;
        else{
            if(type==1) return a[type].st>a[b.type].st;
            else return id>b.id;
        }
    }
};
priority_queue<node>op;

struct Queue{
    int num;
    int id;
    bool operator < (const Queue &aa) const{
        if(num!=aa.num) return num<aa.num;
        else return id<aa.id;
    }
}q[N];
set<Queue>st;

int main(){
    int T; cin>>T;
    while(T--){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].st,&a[i].len);
            a[i].id=i;
            op.push({a[i].st,2,i});  //st_time
        }
        st.clear();
        for(int i=1;i<=m;i++){   //ed_time
            st.insert({0,i});
            tim[i]=0;
            q[i]={0,i};
        }
        while(!op.empty()){   //<time,type,id>
            auto now=op.top();
            op.pop();
            if(now.type==1){  //走
                int qid=q_select[now.id];
                st.erase({q[qid].num,q[qid].id});
                q[qid].num--;
                st.insert({q[qid].num,q[qid].id});
            }
            else{  //来
                auto q_front=*st.begin();
                st.erase(q_front);
                int ind=q_front.id;
                q_select[now.id]=ind;
                if(tim[ind]<a[now.id].st) tim[ind]=a[now.id].st;
                tim[ind]+=a[now.id].len;
                op.push({tim[ind],1,now.id});
                q[ind].num+=1;
                q_front.num+=1;
                st.insert(q_front);
            }
        }   
        ll ans=0;
        for(int i=1;i<=m;i++){
            ans=max(ans,tim[i]);
        }
        printf("%lld\n",ans);
    }

    system("pause");
    return 0;
}

标签:杭电多校,Buy,return,int,第五场,mid,st,type,id
来源: https://www.cnblogs.com/re0acm/p/16546121.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有