• CF378 D. Preparing for the Contest


    题目传送门:https://codeforces.com/problemset/problem/378/D

    题目大意:
    (n) 个人,(m) 个bug,已经总资金(s)

    (i)个bug的难度为(a_i),第(i)个人的能力值为(b_i),其需要的工资为(c_i)

    支付工资(c_i)后,第(i)个人就可以每天处理一个难度不超过(b_i)的bug,持续时间无限

    问能否选出一些人处理这些bug?如果能,输出所需的最少天数(d),以及每个bug是由谁处理的


    考虑二分天数,如果需要花费(d)天解决问题,我们就尽可能让所有人都工作(d)天,至少能力越强的人,越应当工作(d)

    故判断天数(d)是否可行时,我们在剩余的bug中找到最难的一个(k),选取能力值(b_igeqslant a_k)(c_i)最小的一个,然后除去(d)个bug,以此类推直到bug处理完毕

    将能力值作为下标,转化为线段树维护

    注:同一能力值的人有多个

    /*program from Wolfycz*/
    #include<map>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define Fi first
    #define Se second
    #define ll_inf 1e18
    #define MK make_pair
    #define sqr(x) ((x)*(x))
    #define pii pair<int,int>
    #define int_inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    template<typename T>inline T frd(T x){
    	int f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    template<typename T>inline T read(T x){
    	int f=1; char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)	putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e5;
    int B[N+10],C[N+10],list[(N<<1)+10],All,T;
    vector<int>pos[(N<<1)+10],_tmp[(N<<1)+10];
    struct S1{
    	#define ls (p<<1)
    	#define rs (p<<1|1)
    	int Tree[(N<<3)+10],Temp[(N<<3)+10];
    	void copy(){
    		memcpy(Temp,Tree,sizeof(Tree));
    		for (int i=1;i<=T;i++)	_tmp[i]=pos[i];
    	}
    	void paste(){
    		memcpy(Tree,Temp,sizeof(Temp));
    		for (int i=1;i<=T;i++)	pos[i]=_tmp[i];
    	}
    	void update(int p){Tree[p]=C[Tree[ls]]<C[Tree[rs]]?Tree[ls]:Tree[rs];}
    	void update(int &x,int y){x=C[x]<C[y]?x:y;}
    	void Build(int p,int l,int r){
    		if (l==r){
    			Tree[p]=pos[l].empty()?0:pos[l].front();
    			return;
    		}
    		int mid=(l+r)>>1;
    		Build(ls,l,mid);
    		Build(rs,mid+1,r);
    		update(p);
    	}
    	void Modify(int p,int l,int r,int x){
    		if (l==r){
    			pos[l].erase(pos[l].begin());
    			Tree[p]=pos[l].empty()?0:pos[l].front();
    			return;
    		}
    		int mid=(l+r)>>1;
    		if (x<=mid)	Modify(ls,l,mid,x);
    		if (x>mid)	Modify(rs,mid+1,r,x);
    		update(p);
    	}
    	int Query(int p,int l,int r,int L,int R){
    		if (L<=l&&r<=R)	return Tree[p];
    		int mid=(l+r)>>1,Ans=0;
    		if (L<=mid)	update(Ans,Query(ls,l,mid,L,R));
    		if (R>mid)	update(Ans,Query(rs,mid+1,r,L,R));
    		return Ans;
    	}
    	void print(int p,int l,int r){
    		if (l==r)	return;
    		int mid=(l+r)>>1;
    		print(ls,l,mid);
    		print(rs,mid+1,r);
    	}
    	#undef ls
    	#undef rs
    }ST;//Segment Tree
    struct node{
    	int Val,ID;
    	node(int _Val=0,int _ID=0){Val=_Val,ID=_ID;}
    	bool operator <(const node &tis)const{return Val<tis.Val;}
    	void operator =(int x){Val=x;}
    }A[N+10];
    bool check(int x,int m){
    	ST.paste(); ll use=0;
    	for (int i=1;i<=m;i+=x){
    		int pos=ST.Query(1,1,T,A[i].Val,T);
    		use+=C[pos];
    		if (use>All)	return 0;
    		ST.Modify(1,1,T,B[pos]);
    	}
    	return use<=All;
    }
    int Ans[N+10];
    void solve(int x,int m){
    	ST.paste();
    	for (int i=1;i<=m;i+=x){
    		int pos=ST.Query(1,1,T,A[i].Val,T);
    		Ans[A[i].ID]=pos;
    		ST.Modify(1,1,T,B[pos]);
    	}
    	for (int i=1;i<=m;i++)	if (!Ans[A[i].ID])	Ans[A[i].ID]=Ans[A[i-1].ID];
    	printf("YES
    ");
    	for (int i=1;i<=m;i++)	printf("%d%c",Ans[i],i==m?'
    ':' ');
    }
    bool cmp(int x,int y){return C[x]<C[y];}
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	int n=read(0),m=read(0),tot=0; All=read(0); C[0]=int_inf;
    	for (int i=1;i<=m;i++)	A[i]=list[++tot]=read(0);
    	for (int i=1;i<=n;i++)	B[i]=list[++tot]=read(0);
    	for (int i=1;i<=n;i++)	C[i]=read(0);
    	sort(list+1,list+1+tot);
    	T=unique(list+1,list+1+tot)-list-1;
    	for (int i=1;i<=m;i++)	A[i]=lower_bound(list+1,list+1+T,A[i].Val)-list;
    	for (int i=1;i<=n;i++)	B[i]=lower_bound(list+1,list+1+T,B[i]    )-list;
    	for (int i=1;i<=m;i++)	A[i].ID=i;
    	sort(A+1,A+1+m);
    	reverse(A+1,A+1+m);
    	for (int i=1;i<=n;i++)	pos[B[i]].push_back(i);
    	for (int i=1;i<=T;i++)	sort(pos[i].begin(),pos[i].end(),cmp);
    	ST.Build(1,1,T); ST.copy();
    	int l=1,r=m;
    	while (l<=r){
    		int mid=(l+r)>>1;
    		if (check(mid,m))	r=mid-1;
    		else	l=mid+1;
    	}
    	if (r==m){
    		printf("NO
    ");
    		return 0;
    	}
    	solve(r+1,m);
    	return 0;
    }
    
    作者:Wolfycz
    本文版权归作者和博客园共有,欢迎转载,但必须在文章开头注明原文出处,否则保留追究法律责任的权利
  • 相关阅读:
    MIRO校验过程
    SAP中寄售处理
    物料BOM和生产订单BOM的区别
    sap 中怎样把非限制库存转为销售订单库存?
    SAP MM Consignment 寄售库存
    SAP 库存关联表信息
    SAP 物料主数据屏幕增强
    __defineGetter__ && __defineSetter__
    mongodb(分片)
    mongodb(副本集)
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/14960088.html
Copyright © 2020-2023  润新知