zoukankan      html  css  js  c++  java
  • [CTSC2018]混合果汁

    [CTSC2018]混合果汁

    题目大意:

    (n(nle10^5))种果汁,每种果汁有三个属性:美味度(d_i)、单价(p_i)和最大体积(v_i(d_i,p_i,v_ile10^5))。有(m(mle10^5))个人来买混合果汁,并且希望在价格不超过(g_i)的情况下买到体积至少为(l_i(g_i,l_ile10^9))的混合果汁。定义一种混合果汁的美味度为构成此种混合果汁的所有果汁中最小的美味度。求每个人能喝到的美味度最大是多少?

    思路:

    对所有果汁的(d_i)排序。建立主席树维护单价区间能购买到的最大体积之和与总金额之和。对于每个人二分答案(k),在主席树上查找美味度不小于(k),尽可能选择单价小的果汁最多能购买的混合果汁体积。若体积大于(l_i)则说明答案(ge k)。时间复杂度(mathcal O(nlog^2 n))

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    typedef long long int64;
    inline int64 getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int64 x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=1e5+1,logN=18;
    int n,m,lim,tmp[N];
    struct Juice {
    	int d,p,v;
    	bool operator < (const Juice &rhs) const {
    		return d<rhs.d;
    	}
    };
    Juice juice[N];
    class FotileTree {
    	private:
    		struct Node {
    			int64 v,s;
    			int left,right;
    		};
    		Node node[N*logN];
    		int sz,new_node(const int &q) {
    			node[++sz]=node[q];
    			return sz;
    		}
    	public:
    		int root[N];
    		void insert(const int &q,int &p,const int &b,const int &e,const int &g,const int &v) {
    			p=new_node(q);
    			node[p].v+=v;
    			node[p].s+=(int64)g*v;
    			if(b==e) return;
    			const int mid=(b+e)>>1;
    			if(g<=mid) insert(node[q].left,node[p].left,b,mid,g,v);
    			if(g>mid) insert(node[q].right,node[p].right,mid+1,e,g,v);
    		}
    		int64 query(const int &q,const int &p,const int &b,const int &e,const int64 &g) {
    			if(b==e) return std::min(g/b,node[p].v-node[q].v);
    			const int mid=(b+e)>>1;
    			const int64 tmp1=node[node[p].left].s-node[node[q].left].s;
    			const int64 tmp2=node[node[p].left].v-node[node[q].left].v;
    			if(tmp1==g) return tmp2;
    			if(tmp1>g)  {
    				return query(node[q].left,node[p].left,b,mid,g);
    			} else {
    				return tmp2+query(node[q].right,node[p].right,mid+1,e,g-tmp1);
    			}
    		}
    };
    FotileTree t;
    inline bool check(const int &k,const int64 &g,const int64 &v) {
    	return t.query(t.root[tmp[k]-1],t.root[n],1,lim,g)>=v;
    }
    int main() {
    	n=getint(),m=getint();
    	for(register int i=1;i<=n;i++) {
    		const int d=getint(),p=getint(),v=getint();
    		juice[i]=(Juice){d,p,v};
    		lim=std::max(lim,p);
    	}
    	std::sort(&juice[1],&juice[n+1]);
    	for(register int i=1;i<=n;i++) {
    		const int &d=juice[i].d,&p=juice[i].p,&v=juice[i].v;
    		if(d!=juice[tmp[tmp[0]]].d) tmp[++tmp[0]]=i;
    		t.insert(t.root[i-1],t.root[i],1,lim,p,v);
    	}
    	for(register int i=0;i<m;i++) {
    		const int64 g=getint(),v=getint();
    		int l=1,r=tmp[0];
    		while(l<=r) {
    			const int mid=(l+r)>>1;
    			if(check(mid,g,v)) {
    				l=mid+1;
    			} else {
    				r=mid-1;
    			}
    		}
    		printf("%d
    ",check(l-1,g,v)?juice[tmp[l-1]].d:-1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    移动硬盘插入电脑后检测到却不显示如何解决?
    Js求角度、三角形、弧度计算
    Python之常用模块(一)
    PostgreSQL中的MVCC 事务隔离
    520了,用32做个简单的小程序
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    MySQL 返回未包含在group by中的列
    《Mysql日志备份/恢复》大型详细攻略两万字图解(史上最详细,多图)
    年轻就该多尝试,教你20小时Get一项新技能
    Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
  • 原文地址:https://www.cnblogs.com/skylee03/p/9105476.html
Copyright © 2011-2022 走看看