zoukankan      html  css  js  c++  java
  • 【有趣的有趣的家庭菜园】题解

    分析

    设f[i]指1i没有比i更高的草是,1i的收益。
    显然转移为,当h[j]<=h[i]$$f[i]=max(f[j]-sum_{j<k<i 且 h[k]>h[i] }{c[k]})+p[i]$$
    然后设g[i]指in没有比i更高的草是,in的收益。转移同上。答案就是max(f[i]+g[i]-p[i]),O(n^3),超时。
    如何优化呢?由于n<=100000,就离散化h,以高度搞个有标记线段树,记录$$max(f[j]-sum_{j<k<i 且 h[k]>h[i] }{c[k]})$$。然后每次把小于等于h[i]的线段树的最大值取出来,把f[i]放入线段树,再把小于h[i]的都减去c[i]。

    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    const long long maxlongint=2147483647;
    using namespace std;
    long long tree[400000],f[200000],g[200000],n,m,ans,tot,h[200000],p[200000],c[200000],bef[200000],reh[200000],dee[400000];
    void q(long long l,long long r)
    {
    	long long i=l,j=r,mid=reh[(l+r)/2],e;
    	while(i<j)
    	{
    		while(reh[i]<mid) i++;
    		while(reh[j]>mid) j--;
    		if(i<=j)
    		{
    			e=reh[i];
    			reh[i]=reh[j];
    			reh[j]=e;
    			e=bef[i];
    			bef[i]=bef[j];
    			bef[j]=e;
    			i++;
    			j--;
    		}
    	}
    	if(i<r) q(i,r);
    	if(l<j) q(l,j);
    }
    long long disc()
    {
    	long long k;
    	q(1,n);
    	k=0;
    	for(long long i=1;i<=n;i++)
    	{
    		if(reh[i]!=reh[i-1])
    			k++;
    		h[bef[i]]=k;
    	}
    }
    long long find(long long v,long long l,long long r,long long x,long long y)
    { 
    	if(l==x && r==y)
    	{
    		return tree[v];
    	}
    	if(tree[v*2]!=tree[0])
    	{
    		tree[v*2]-=dee[v];
    		dee[v*2]+=dee[v];
    	}
    	else
    	{
    		tree[v*2]=-dee[v];
    		dee[v*2]+=dee[v];
    	}
    	if(tree[v*2+1]!=tree[0])
    	{
    		tree[v*2+1]-=dee[v];
    		dee[v*2+1]+=dee[v];
    	}
    	else
    	{
    		tree[v*2+1]=-dee[v];
    		dee[v*2+1]+=dee[v];
    	}
    	dee[v]=0;
    	long long mid=(l+r)/2,t,t1;
    	if(y<=mid)
    	{
    		return find(v*2,l,mid,x,y);
    	}
    			else
    				if(x>mid)
    					return find(v*2+1,mid+1,r,x,y);
    						else 
    						{
    							return max(find(v*2,l,mid,x,mid),find(v*2+1,mid+1,r,mid+1,y));
    						}
    	return t;
    }
    long long put(long long v,long long l,long long r,long long hi,long long pu)
    {
    	if(l==r)
    	{
    		tree[v]=max(tree[v],pu);
    		return 0;
    	}
    	if(tree[v*2]!=tree[0])
    	{
    		tree[v*2]-=dee[v];
    		dee[v*2]+=dee[v];
    	}
    	else
    	{
    		tree[v*2]=-dee[v];
    		dee[v*2]+=dee[v];
    	}
    	if(tree[v*2+1]!=tree[0])
    	{
    		tree[v*2+1]-=dee[v];
    		dee[v*2+1]+=dee[v];
    	}
    	else
    	{
    		tree[v*2+1]=-dee[v];
    		dee[v*2+1]+=dee[v];
    	}
    	dee[v]=0;
    	long long mid=(l+r)/2;
    	if(hi<=mid)
    	{	
    		put(v*2,l,mid,hi,pu);
    		tree[v]=max(tree[v*2+1],tree[v*2]);
    	}
    	else
    	{
    		put(v*2+1,mid+1,r,hi,pu);
    		tree[v]=max(tree[v*2],tree[v*2+1]);	
    	}
    	tree[v]=max(tree[v*2],tree[v*2+1]);
    }
    long long de(long long v,long long l,long long r,long long x,long long y,long long d)
    {
    	if(l==x && r==y)
    	{
    		dee[v]+=d;
    		tree[v]-=d;
    		return 0;
    	}
    	if(tree[v*2]!=tree[0])
    	{
    		tree[v*2]-=dee[v];
    		dee[v*2]+=dee[v];
    	}
    	else
    	{
    		tree[v*2]=-dee[v];
    		dee[v*2]+=dee[v];
    	}
    	if(tree[v*2+1]!=tree[0])
    	{
    		tree[v*2+1]-=dee[v];
    		dee[v*2+1]+=dee[v];
    	}
    	else
    	{
    		tree[v*2+1]=-dee[v];
    		dee[v*2+1]+=dee[v];
    	}
    	dee[v]=0;
    	long long mid=(l+r)/2;
    	if(y<=mid)
    		de(v*2,l,mid,x,y,d);
    			else
    				if(x>mid)
    					de(v*2+1,mid+1,r,x,y,d);
    						else de(v*2,l,mid,x,mid,d),de(v*2+1,mid+1,r,mid+1,y,d);
    	tree[v]=max(tree[v*2],tree[v*2+1]);	
    }
    int main()
    {
    	scanf("%lld
    ",&n);
    	long long i,j,k;
    	for(i=1;i<=n;i++)
    	{
    		scanf("%lld%lld%lld
    ",&reh[i],&p[i],&c[i]);
    		bef[i]=i;
    	}
    	disc();
    	memset(tree,200,sizeof(tree));
    	put(1,0,n,0,0);
    	memset(dee,0,sizeof(dee));
    	for(i=1;i<=n;i++)
    	{
    		f[i]=find(1,0,n,0,h[i])+p[i];
    		put(1,0,n,h[i],f[i]);
    		
    		de(1,0,n,0,h[i]-1,c[i]);
    	}
    	memset(tree,200,sizeof(tree));
    	put(1,0,n,0,0);
    	memset(dee,0,sizeof(dee));
    	ans=0;
    	for(i=n;i>=1;i--)
    	{
    		g[i]=find(1,0,n,0,h[i])+p[i];
    		put(1,0,n,h[i],g[i]);
    		de(1,0,n,0,h[i]-1,c[i]);
    	}
        for(i=1;i<=n;i++)
        	ans=max(ans,f[i]-p[i]+g[i]);
    	printf("%lld
    ",ans);
    }
    
    
    
    
    
  • 相关阅读:
    Python 集合
    Python sorted()
    CodeForces 508C Anya and Ghosts
    CodeForces 496B Secret Combination
    CodeForces 483B Friends and Presents
    CodeForces 490C Hacking Cypher
    CodeForces 483C Diverse Permutation
    CodeForces 478C Table Decorations
    CodeForces 454C Little Pony and Expected Maximum
    CodeForces 313C Ilya and Matrix
  • 原文地址:https://www.cnblogs.com/chen1352/p/9008558.html
Copyright © 2011-2022 走看看