【Codeforces 377D】—Developing Game(线段树+扫描线)

传送门

考虑对于一种方案
最后一定存在2个数L,RL,R满足L[max(li),min(vi)],R[max(vi),min(ri)]Lin[max(l_i),min(v_i)],Rin[max(v_i),min(r_i)]
换个角度
如果把L,RL,R看做一个二维的点
那么就是找一个L,RL,R使得被最多的x[l,v],y[v,r]xin[l,v],yin[v,r]这样的矩阵覆盖

扫描线搞一下就完了

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
    static char ibuf[RLEN],*ib,*ob;
    (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
    char ch=gc();
    int res=0,f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int N=300005;
namespace Seg{
	int tag[N<<2],mx[N<<2],pos[N<<2];
	#define lc (u<<1)
	#define rc ((u<<1)|1)
	#define mid ((l+r)>>1)
	inline void pushup(int u){
		if(mx[lc]<mx[rc])mx[u]=mx[rc],pos[u]=pos[rc];
		else mx[u]=mx[lc],pos[u]=pos[lc];
	}
	inline void pushnow(int u,int k){
		mx[u]+=k,tag[u]+=k;
	}
	inline void pushdown(int u){
		if(!tag[u])return;
		pushnow(lc,tag[u]),pushnow(rc,tag[u]);
		tag[u]=0;
	}
	void build(int u,int l,int r){
		if(l==r){mx[u]=0,pos[u]=l;return ;}
		build(lc,l,mid),build(rc,mid+1,r);
		pushup(u);
	}
	void update(int u,int l,int r,int st,int des,int k){
		if(st<=l&&r<=des)return pushnow(u,k);
		pushdown(u);
		if(st<=mid)update(lc,l,mid,st,des,k);
		if(mid<des)update(rc,mid+1,r,st,des,k);
		pushup(u);
	}
}
int n,l[N],r[N],v[N];
struct opt{
	int l,r,v;
	opt(int _l=0,int _r=0,int _v=0):l(_l),r(_r),v(_v){}
};
vector<opt> e[N];
int main(){
	n=read();
	for(int i=1;i<=n;i++)l[i]=read(),v[i]=read(),r[i]=read();
	for(int i=1;i<=n;i++){
		if(l[i]<=v[i]&&v[i]<=r[i]){
			e[v[i]].pb(opt(l[i],v[i],1));
			e[r[i]+1].pb(opt(l[i],v[i],-1));
		}
	}
	Seg::build(1,1,300000);
	int mx=0;pii mxpos;
	for(int i=1;i<=300000;i++){
		for(opt &x:e[i]){
			Seg::update(1,1,300000,x.l,x.r,x.v);
		}
		int v=Seg::mx[1];
		if(v>mx)mxpos=pii(i,Seg::pos[1]),mx=v;
	}
	cout<<mx<<'
';
	for(int i=1;i<=n;i++){
		if(l[i]<=v[i]&&v[i]<=r[i]){
			if(l[i]<=mxpos.se&&mxpos.se<=v[i]&&v[i]<=mxpos.fi&&mxpos.fi<=r[i])cout<<i<<" ";
		}
	}puts("");
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328552.html