zoukankan      html  css  js  c++  java
  • [bzoj5343][loj2555]: [Ctsc2018]混合果汁 (二分答案+主席树)

    www.cnblogs.com/shaokele/


    p1
    p2
    p3

    题目地址:  [loj2555]: [Ctsc2018]混合果汁

    题目大意:   题目很简洁了:)####

      

    题解:

      二分答案,用主席树维护贪心操作
      
      先按 (d) 排序,二分 (ans) **
      
      
    主席树操作判断是否符合**
      
      细节注意
      


    AC代码

    #include <cstdio> 
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int N=1e5+5,M=1800005;
    int n,Q,sz,mxd,mxp;
    int ls[M],rs[M],root[M];
    ll g,L;
    ll s[N],sum[M],val[M];
    inline ll read(){	
    	ll x=0;int f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){
    		if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){
    		x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    struct node{
    		int d,p,l;
    }A[N];
    bool operator < (const node &a,const node &b){
    		return a.d<b.d; 
    }
    void insert(int l,int r,int &u,int pre,int p,int L){
    	u=++sz;
    	sum[u]=sum[pre];val[u]=val[pre];
    	ls[u]=ls[pre];rs[u]=rs[pre];
    	sum[u]+=L;val[u]+=1ll*p*L;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	if(p<=mid)insert(l,mid,ls[u],ls[pre],p,L);
    	else insert(mid+1,r,rs[u],rs[pre],p,L);
    }
    ll ask(int l,int r,int u,int pre,ll L){
    	if(!u)return 0;
    	if(l==r)return L*l;
    	int mid=(l+r)>>1;
    	ll tmp=sum[ls[u]]-sum[ls[pre]];
    	if(tmp>=L)return ask(l,mid,ls[u],ls[pre],L);
    	else return val[ls[u]]-val[ls[pre]]+ask(mid+1,r,rs[u],rs[pre],L-tmp);
    }
    bool check(int mid,ll g,ll L){
    	int pre=lower_bound(A+1,A+n+1,(node){mid,0,0})-A-1;
    	if(s[n]-s[pre]<L)return 0;
    	else return ask(1,mxp,root[n],root[pre],L)<=g;
    }
    int main(){
    	n=read(),Q=read();
    	for(int i=1;i<=n;i++){
    		A[i].d=read(),A[i].p=read(),A[i].l=read();
    		mxd=max(mxd,A[i].d);
    		mxp=max(mxp,A[i].p);
    	}
    	sort(A+1,A+n+1);
    	for(int i=1;i<=n;i++)
    		s[i]=s[i-1]+A[i].l;
    	for(int i=1;i<=n;i++)
    		insert(1,mxp,root[i],root[i-1],A[i].p,A[i].l);
    	while(Q--){
    		g=read(),L=read();
    		int l=1,r=mxd,ans=-1;
    		while(l<=r){
    			int mid=(l+r)/2;
    			if(check(mid,g,L)){
    				ans=mid;
    				l=mid+1;
    			}else r=mid-1;
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    《构建之法》1.2.3章读后感
    0302思考并回答一些问题
    1231 实验四 递归下降语法分析程序设计
    1211 有穷自动机的构造与识别
    1112-评论
    C语言文法定义及C程序的推导过程
    词法分析
    0909对编译原理的理解
    团队合作2.0
    "数学口袋精灵"bug的发现及单元测试
  • 原文地址:https://www.cnblogs.com/shaokele/p/9109071.html
Copyright © 2011-2022 走看看