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

    前言

    先写思路后码代码,应该是对的,等我写完验证一下就知道了。

    update 2021.4.6 写完了,一遍过。

    题目

    洛谷

    讲解

    我们先思考这样一个事情:如果规定一些果汁可以选,那么我们显然可以贪心选这些果汁中单价最少的判断是否可以满足一个小朋友的要求。

    当然我们也可以将其放到线段树上,以价格为下标,查询的时候可以在线段树上二分。

    显然我们要二分果汁美味度,以标记可以选的果汁有哪些,我们显然不能重新建树,为了保证时间复杂度,我们用主席树来动态维护前缀和。

    多个小朋友?整体二分即可(似乎不用整体二分而直接做 (m) 次二分也行,只是常数稍微大了一点点)。

    每个孩子在二分时最多会在主席树上查询 (log_2n) 次,时间复杂度应该是 (O(nlog_2^2n)) 级别。

    代码

    小常数!

    struct Juice
    {
    	int d,p,l;//美味度 单价 上限 
    	bool operator < (const Juice &px)const{
    		return d < px.d;
    	}
    }s[MAXN];
    struct Children
    {
    	LL g,L;
    	int ID;
    }c[MAXN],c2[MAXN];
    int rt[MAXN];
    struct PresidentTree
    {
    	int tot;
    	struct node
    	{
    		int ch[2];
    		LL P,V;//总价钱  总体积 
    	}t[MAXN * 30];
    	
    	void Add(int lst,int &now,int l,int r,Juice ad)
    	{
    		now = ++tot;
    		t[now] = t[lst];
    		t[now].P += 1ll * ad.p * ad.l; 
    		t[now].V += ad.l;
    		if(l == r) return;
    		int mid = (l+r) >> 1;
    		if(ad.p <= mid) Add(t[lst].ch[0],t[now].ch[0],l,mid,ad);
    		else Add(t[lst].ch[1],t[now].ch[1],mid+1,r,ad);
    	}
    	
    	bool Query(int lst,int now,int l,int r,Children A)
    	{
    		if(t[now].V - t[lst].V < A.L) return 0;
    		if(t[now].V - t[lst].V >= A.L && A.g >= t[now].P - t[lst].P) return 1;
    		if(l == r) return A.g / l >= A.L;
    		int mid = (l+r) >> 1;
    		if(t[t[now].ch[0]].V - t[t[lst].ch[0]].V >= A.L) return Query(t[lst].ch[0],t[now].ch[0],l,mid,A);
    		else if(t[t[now].ch[0]].P - t[t[lst].ch[0]].P > A.g) return 0;
    		else 
    		{
    			A.g -= t[t[now].ch[0]].P - t[t[lst].ch[0]].P;
    			A.L -= t[t[now].ch[0]].V - t[t[lst].ch[0]].V;
    			return Query(t[lst].ch[1],t[now].ch[1],mid+1,r,A);
    		}
    	}
    }pt;
    
    void solve(int l,int r,int cl,int cr)
    {
    	int mid = (l+r) >> 1;
    	int tot1 = cl,tot2 = 0;
    	for(int i = cl;i <= cr;++ i)
    	{
    		if(pt.Query(rt[ef[mid]-1],rt[n],1,MAX,c[i])) ans[c[i].ID] = s[ef[mid]].d,c2[++tot2] = c[i];
    		else c[tot1++] = c[i];
    	}
    	if(l == r) return;
    	for(int i = 1;i <= tot2;++ i) c[tot1+i-1] = c2[i];
    	solve(l,mid,cl,tot1-1); solve(mid+1,r,tot1,cr);
    }
    
    int main()
    {
    
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read(); m = Read();
    	for(int i = 1;i <= n;++ i) s[i].d = Read(),s[i].p = Read(),s[i].l = Read(),MAX = Max(MAX,s[i].p);
    	for(int i = 1;i <= m;++ i) c[i].g = Read(),c[i].L = Read(),c[i].ID = i;
    	sort(s+1,s+n+1);
    	for(int i = 1;i <= n;++ i) 
    	{
    		pt.Add(rt[i-1],rt[i],1,MAX,s[i]);
    		if(s[i].d != s[i-1].d) ef[++nn] = i;
    	}
    	solve(1,nn,1,m);
    	for(int i = 1;i <= m;++ i) Put(ans[i] ? ans[i] : -1,'
    ');
    	return 0;
    }
    

    后记

    目前洛谷rk1。

  • 相关阅读:
    用网线连接Windows和Linux台式机,并实现Linux共享Windows的WiFi网络
    设计模式之建造者设计模式
    Mob之社会化分享集成ShareSDK
    Mob 之 短信验证集成 SMSSDK
    天地图值之添加覆盖物
    天地图之定位信息详解
    Material Design 组件之NavigationView
    Material Design 组件之 CollapsingToolbarLayout
    Material Design 组件之 AppBarLayout
    Material Design 组件之 FloatingActionButton
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14514687.html
Copyright © 2011-2022 走看看