Developing Game
题解
很容易发现题目要可以转化为,
于是,我们需要找到一个使得
。
我们可以将所需要找的看做二维坐标系上的一个点,将每个人的情况看做一个矩阵,将每个矩阵覆盖到坐标系上,要求的即被最多矩阵覆盖的那个点。
于是,我们可以用一棵线段树维护当前值时每个点的覆盖情况,将
的所有
值全部扫一遍,当矩形进入时加上,退出时减去即可。
由于只有加入与退出时才会对整个线段树的值造成影响,可以将其进行离散化,最后时间复杂度。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define MAXM 600005
const int INF=0x7f7f7f7f;
const int mo=1e9+7;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<LL,LL> pii;
int n;
struct ming{int v,l,r;}a[MAXN];
struct seg{int x,u,d;bool b;}s[MAXN];
int val[MAXM<<2],lzy[MAXM<<2],pos[MAXM<<2];
void pushdown(int rt){
if(!lzy[rt])return ;
val[rt<<1]+=lzy[rt];val[rt<<1|1]+=lzy[rt];
lzy[rt<<1]+=lzy[rt];lzy[rt<<1|1]+=lzy[rt];
lzy[rt]=0;
}
void pushup(int rt){
if(val[rt<<1]>val[rt<<1|1])
pos[rt]=pos[rt<<1],val[rt]=val[rt<<1];
else pos[rt]=pos[rt<<1|1],val[rt]=val[rt<<1|1];
}
void modify(int rt,int l,int r,int al,int ar,int aw){
if(l>r||al>r||ar<l)return ;
if(al<=l&&r<=ar){val[rt]+=aw;lzy[rt]+=aw;return ;}
int mid=l+r>>1;pushdown(rt);
if(al<=mid)modify(rt<<1,l,mid,al,ar,aw);
if(mid<ar)modify(rt<<1|1,mid+1,r,al,ar,aw);
pushup(rt);
}
void build(int rt,int l,int r){
if(l==r)return (void)(pos[rt]=l);
int mid=l+r>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pos[rt]=pos[rt<<1];
}
bool cmp(seg x,seg y){
if(x.x==y.x)return x.b<y.b;
return x.x<y.x;
}
signed main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d %d %d",&a[i].l,&a[i].v,&a[i].r);
s[i<<1]=(seg){a[i].l,a[i].r,a[i].v,0};
s[i<<1|1]=(seg){a[i].v,a[i].r,a[i].v,1};
}
build(1,1,3e5+1);sort(s,s+(n<<1),cmp);
int ans=0,ansp=0,ansx=0;
for(int i=0;i<(n<<1);i++){
modify(1,1,3e5+1,s[i].d,s[i].u,s[i].b?-1:1);
if(val[1]>ans)ans=val[1],ansp=pos[1],ansx=s[i].x;
}
printf("%d\n",ans);
for(int i=0;i<n;i++)
if(a[i].l<=ansx&&ansx<=a[i].v&&a[i].v<=ansp&&ansp<=a[i].r)
printf("%d ",i+1);
puts("");
return 0;
}