zoukankan      html  css  js  c++  java
  • [CF542A]Place Your Ad Here

    [CF542A]Place Your Ad Here

    题目大意:

    (n(nle2 imes10^5))个广告和(m(mle2 imes10^5))个电视台,第(i)个广告只能在([l_i,r_i])内播放,第(j)个电视台会在时间段([a_j,b_j])播出,并且有(c_j)个人收看。选择第(x)个广告和第(y)个电视台的收益为((v-u)c_y),其中([u,v]=[l_x,r_x]cap[a_y,b_y])
    从中选取一个广告和一个电视台,使收益最大。求最大收益,并输出任意一种方案。

    思路:

    将广告拆成两个端点排序,将电视台按照右端点排序。

    枚举每个电视台([l,r]),若一个广告只有左端点在(r)前,那么我们只关心最左的左端点;若一个广告左右端点均在([l,r])内,那么我们只关心其长度;若一个广告左端点在(l)前,右端点在([l,r])内,那么我们只关心其右端点的位置。

    对于第一种情况,用set维护即可;后两种情况只需用线段树维护区间最大值。

    时间复杂度(mathcal O(nlog n))

    源代码:

    #include<set>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    typedef long long int64;
    struct Node {
    	int p,id;
    	bool operator < (const Node &rhs) const {
    		return p<rhs.p;
    	}
    };
    struct Seg {
    	int l,r,w,id;
    	bool operator < (const Seg &rhs) const {
    		return r<rhs.r;
    	}
    };
    const int N=2e5+1,K=8e5+1;
    Node a[N],b[N];
    Seg c[N];
    int rnk[N],tmp[K];
    class SegmentTree {
    	#define _left <<1
    	#define _right <<1|1
    	#define mid ((b+e)>>1)
    	private:
    		std::pair<int,int> val[K<<2];
    		void push_up(const int &p) {
    			val[p]=std::max(val[p _left],val[p _right]);
    		}
    	public:
    		void modify(const int &p,const int &b,const int &e,const int &x,const std::pair<int,int> &v) {
    			if(b==e) {
    				val[p]=std::max(val[p],v);
    				return;
    			}
    			if(x<=mid) modify(p _left,b,mid,x,v);
    			if(x>mid) modify(p _right,mid+1,e,x,v);
    			push_up(p);
    		}
    		std::pair<int,int> query(const int &p,const int &b,const int &e,const int &l,const int &r) const {
    			if(b==l&&e==r) return val[p];
    			std::pair<int,int> ret(0,0);
    			if(l<=mid) ret=std::max(ret,query(p _left,b,mid,l,std::min(mid,r)));
    			if(r>mid) ret=std::max(ret,query(p _right,mid+1,e,std::max(mid+1,l),r));
    			return ret;
    		}
    	#undef _left
    	#undef _right
    	#undef mid
    };
    SegmentTree t1,t2;
    std::set<std::pair<int,int> > set;
    int main() {
    	const int n=getint(),m=getint();
    	int tot=0;
    	for(register int i=1;i<=n;i++) {
    		const int l=getint(),r=getint();
    		a[i]=(Node){l,i};
    		b[i]=(Node){r,i};
    		tmp[++tot]=l;
    		tmp[++tot]=r;
    	}
    	for(register int i=1;i<=m;i++) {
    		tmp[++tot]=c[i].l=getint();
    		tmp[++tot]=c[i].r=getint();
    		c[i].w=getint();
    		c[i].id=i;
    	}
    	std::sort(&tmp[1],&tmp[tot]+1);
    	for(register int i=1;i<=n;i++) {
    		a[i].p=std::lower_bound(&tmp[1],&tmp[tot]+1,a[i].p)-tmp;
    		b[i].p=std::lower_bound(&tmp[1],&tmp[tot]+1,b[i].p)-tmp;
    	}
    	for(register int i=1;i<=m;i++) {
    		c[i].l=std::lower_bound(&tmp[1],&tmp[tot]+1,c[i].l)-tmp;
    		c[i].r=std::lower_bound(&tmp[1],&tmp[tot]+1,c[i].r)-tmp;
    	}
    	std::sort(&a[1],&a[n]+1);
    	std::sort(&b[1],&b[n]+1);
    	std::sort(&c[1],&c[m]+1);
    	for(register int i=1;i<=n;i++) {
    		rnk[a[i].id]=i;
    	}
    	int64 ans=0;
    	int x,y;
    	for(register int i=1,j=1,k=1;i<=m;i++) {
    		for(;j<=n&&a[j].p<=c[i].r;j++) {
    			set.insert(std::make_pair(tmp[a[j].p],a[j].id));
    		}
    		for(;k<=n&&b[k].p<=c[i].r;k++) {
    			const int j=rnk[b[k].id];
    			set.erase({tmp[a[j].p],a[j].id});
    			t1.modify(1,1,tot,a[j].p,{tmp[b[k].p]-tmp[a[j].p],a[j].id});
    			t2.modify(1,1,tot,a[j].p,{tmp[b[k].p],a[j].id});
    		}
    		//-: ad
    		//=: tv
    		int len=0,z=0;
    		if(!set.empty()) {
    			//  ------
    			//======
    			const int t=tmp[c[i].r]-std::max(tmp[c[i].l],set.begin()->first);
    			if(t>len) {
    				len=t;
    				z=set.begin()->second;
    			}
    		}
    		{
    			//  --
    			//======
    			const auto p=t1.query(1,1,tot,c[i].l,c[i].r);
    			if(p.first>len) {
    				len=p.first;
    				z=p.second;
    			}
    		}
    		{
    			//------
    			//  ======
    			const auto p=t2.query(1,1,tot,1,c[i].l);
    			if(p.first-tmp[c[i].l]>len) {
    				len=p.first-tmp[c[i].l];
    				z=p.second;
    			}
    		}
    		if(1ll*len*c[i].w>ans) {
    			ans=1ll*len*c[i].w;
    			x=z,y=c[i].id;
    		}
    	}
    	printf("%lld
    ",ans);
    	if(ans) printf("%d %d
    ",x,y);
    	return 0;
    }
    
  • 相关阅读:
    软件产品案例分析 ——华为软件开发云
    软件工程实践2017第一次作业
    软件工程实践2017结对第二次作业
    SDN第一次作业
    路由器工作原理
    Spring框架之springweb web源码完全解析
    Spring框架之springweb http源码完全解析
    Spring框架之jms源码完全解析
    Spring框架之AOP源码完全解析
    比特币里的计算机知识
  • 原文地址:https://www.cnblogs.com/skylee03/p/10217846.html
Copyright © 2011-2022 走看看