BZOJ 2501 SodaMachine苏打贩卖机
2017.06.19
2017.06.19
给你一些区间,请求一个点使得这个点所在的区间数量最多。区间数量50000,区间L,R大小$\le 10^9$.
这道题首先我们发现LR只需要维护相对关系(并查集?)所以1e9完全可以离散化到区间数量1e5
之后我们发现查分完全可以满足我们的需求——大量更改每个只需要O(1),只有一次查询O(1e5)可以接受。
关键是离散化写法。
这里我们使用一个结构体存储每个元素(L,R一视同仁),VAL表示这个值,NUM表示他在第几个区间里,FLG记录他是左端点还是右端点。之后我们按照VAL进行第一次排序,进行离散化(具体看代码),之后进行第二次Sort(注:在这道题中第二次排序可以省略,因为可以直接打标记,但是为了使得代码更加规范自己忘记考虑还是写上吧)
之后我们设立ans数组记录个数。对于每一个左端点将值+1,(右端点+1)的位置-1(否则会出错,因为你需要此时删掉这个区间),之后从头加到尾,每加上一个数就进行一次判断更新最终的答案,之后输出答案就可以了。
//Code Migration
#include <cstdio>
#include <algorithm>
using namespace std;
struct query
{
int val,num,flg;
}q[100010];
int ans,n,f[100010];
bool cmpa(query tx,query ty){return tx.val<ty.val;}
bool cmpb(query tx,query ty){if(tx.flg==ty.flg)return tx.num<ty.num;return tx.flg<ty.flg;}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d%d",&q[i].val,&q[i+n].val);
for(int i=1;i<=n;++i) q[i+n].val++,q[i].flg=1,q[n+i].flg=2,q[i].num=q[n+i].num=i;
n<<=1;
sort(q+1,q+n+1,cmpa);
int tmpa=0,tmpb=0;
for(int i=1;i<=n;++i)
{
if(tmpa!=q[i].val) ++tmpb,tmpa=q[i].val;
q[i].val=tmpb;
}
sort(q+1,q+n+1,cmpb);
n>>=1;
for(int i=1;i<=n;++i) f[q[i].val]++,f[q[n+i].val]--;
tmpa=0;
for(int i=1;i<=tmpb+5;++i)
{
//printf("%d %d %d\n",ans,f[i],tmpa);
tmpa+=f[i];
ans=max(ans,tmpa);
}
//for(int i=1;i<=n;++i) printf("%d %d %d %d\n",q[i].val,q[i].num,q[n+i].val,q[n+i].num);
printf("%d",ans);
return 0;
}