题解:P15482 [CERC2012] Jewel heist
__WBJ0429__ · · 题解
差点场切了,没注意到细节问题。
首先,既然必须有一组宝石不能被区间包含,那么我们就可以钦定颜色为
那么,这里需要分两种情况。
第一种是钦定一个红点
然后注意一下边界即可。这个就是模版单调栈,不过要做两遍。
然后这就是二维数点问题了。直接离散化后用扫描线和树状数组即可。
第二种就是我场上没考虑到的,就是这种情况也可以:
可以发现,只有在两个
::::success[Code]
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fir first
#define sec second
#define is insert
#define es erase
#define pb push_back
#define eb emplace_back
using namespace std;
const int N=2e5+5;
const int INF=1e9+7;
int T,n,k,nxtl[N],nxtr[N],tr[N],ans,st[N];
struct node{
int x,y,c;
}f[N];
inline bool cmp1(const node&PP,const node&QQ){
return PP.x<QQ.x;
}
inline bool cmp2(const node&PP,const node&QQ){
return PP.y<QQ.y;
}
vector<int>rec[N];
vector<int>xs,ys;
struct Q{
int l,r,w;
inline bool operator<(const Q&oth)const{
return w<oth.w;
}
}q[N];
inline int lowbit(int x){
return x&-x;
}
inline void add(int x){
for(;x<=n+2;x+=lowbit(x)){
tr[x]++;
}
}
inline int ask(int x){
int res=0;
for(;x;x-=lowbit(x)){
res+=tr[x];
}
return res;
}
inline void solve(){
ans=0;
cin>>n>>k;
for(int i=0;i<=n+2;i++){
tr[i]=0;
}
xs.clear(),ys.clear();
for(int i=1;i<=k;i++){
rec[i].clear();
}
f[0].x=0,f[0].y=0;
f[n+1].x=INF,f[n+1].y=0;
xs.eb(0);
xs.eb(INF);
ys.eb(0);
for(int i=1;i<=n;i++){
cin>>f[i].x>>f[i].y>>f[i].c;
xs.eb(f[i].x);
ys.eb(f[i].y);
}
sort(xs.begin(),xs.end());
sort(ys.begin(),ys.end());
xs.es(unique(xs.begin(),xs.end()),xs.end());
ys.es(unique(ys.begin(),ys.end()),ys.end());
for(int i=0;i<=n+1;i++){
f[i].x=lower_bound(xs.begin(),xs.end(),f[i].x)-xs.begin();
f[i].y=lower_bound(ys.begin(),ys.end(),f[i].y)-ys.begin();
}
sort(f+1,f+n+1,cmp1);
for(int i=1;i<=n;i++){
rec[f[i].c].eb(i);
nxtr[i]=n+1;
nxtl[i]=0;
}
for(int i=1;i<=k;i++){
int top=0;
for(int j=0;j<rec[i].size();j++){
while(top&&f[rec[i][j]].y<f[rec[i][st[top]]].y){
nxtr[rec[i][st[top]]]=rec[i][j];
top--;
}
st[++top]=j;
}
top=0;
for(int j=rec[i].size()-1;j>=0;j--){
while(top&&f[rec[i][j]].y<f[rec[i][st[top]]].y){
nxtl[rec[i][st[top]]]=rec[i][j];
top--;
}
st[++top]=j;
}
}
for(int i=1;i<=n;i++){
q[i].l=f[nxtl[i]].x+1;
q[i].r=f[nxtr[i]].x-1;
q[i].w=f[i].y-1;
}
for(int i=1;i<=k;i++){
for(int &j:rec[i]){
j=f[j].x;
}
}
sort(f+1,f+n+1,cmp2);
sort(q+1,q+n+1);
int p=1;
for(int i=1;i<=n;i++){
while(p<=n&&f[p].y<=q[i].w){
add(f[p].x);
p++;
}
ans=max(ans,ask(q[i].r)-ask(q[i].l-1));
}
while(p<=n){
add(f[p].x);
p++;
}
for(int i=1;i<=k;i++){
if(rec[i].empty())continue;
for(int j=0;j<rec[i].size()-1;j++){
ans=max(ans,ask(rec[i][j+1]-1)-ask(rec[i][j]));
}
ans=max(ans,ask(rec[i][0]-1));
ans=max(ans,ask(n+2)-ask(rec[i].back()));
}
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>T;
while(T--){
solve();
}
}
::::