题意
给定N(N<=200000)个矩阵,询问有多少个矩阵被别的矩阵包含。
思路
看到数据范围以为要
O(nlog2n)
O
(
n
l
o
g
2
n
)
的方法,想了半天也不会,一搜题解,哈哈哈,
O(nlog22n)
O
(
n
l
o
g
2
2
n
)
就能过。
考虑
cdq
c
d
q
分治,对
x1
x
1
排序,
y1
y
1
用归并排序处理,线段树维护
x2,y2
x
2
,
y
2
。
可以说是裸题吧。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int read(){
int rt=0,fl=1;char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
fl=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
rt=(rt<<3)+(rt<<1)+ch-'0';
ch=getchar();
}
return rt*fl;
}
struct data{
int a,b,c,d,id;
bool chosen;
data(){}
data(int q,int w,int e,int r,int t){
a=q;
b=w;
c=e;
d=r;
id=t;
chosen=false;
}
};
bool cmp(data a,data b){
return a.a<b.a;
}
bool cmp2(data a,data b){
return a.c<b.c;
}
const int N=200005;
int n,number[N*4],cnt;
data sq[N],buf[N];
bool tag[N];
int mx[N<<2],mxX;
void update(int x){
mx[x]=max(mx[x<<1],mx[x<<1|1]);
}
void modify(int c,int l,int r,int loc,int v){
if(l==r){
mx[c]+=v;
return;
}
int mid=(l+r)>>1;
if(loc<=mid)
modify(c<<1,l,mid,loc,v);
else
modify(c<<1|1,mid+1,r,loc,v);
update(c);
}
int query(int c,int l,int r,int x,int y){
if(l==x&&r==y)
return mx[c];
int mid=(l+r)>>1;
if(y<=mid)
return query(c<<1,l,mid,x,y);
else if(x>mid)
return query(c<<1|1,mid+1,r,x,y);
else
return max(query(c<<1,l,mid,x,mid),query(c<<1|1,mid+1,r,mid+1,y));
}
void solve(int l,int r){
if(l==r)
return;
int mid=(l+r)>>1;
solve(l,mid);
for(int i=l;i<=mid;i++)
sq[i].chosen=1;
solve(mid+1,r);
for(int i=mid+1;i<=r;i++)
sq[i].chosen=0;
int p1=l,p2=mid+1;
for(int i=l;i<=r;i++){
if(p1<=mid&&p2<=r){
if(sq[p1].b<sq[p2].b){
buf[i]=sq[p1++];
}else{
buf[i]=sq[p2++];
}
}else if(p1<=mid){
buf[i]=sq[p1++];
}else{
buf[i]=sq[p2++];
}
}
for(int i=l;i<=r;i++)
sq[i]=buf[i];
for(int i=l;i<=r;i++){
if(sq[i].chosen){
modify(1,1,mxX,sq[i].c,sq[i].d);
}else{
int t=query(1,1,mxX,sq[i].c,mxX);
if(t>sq[i].d){
tag[sq[i].id]=1;
}
}
}
for(int i=l;i<=r;i++)
if(sq[i].chosen)
modify(1,1,mxX,sq[i].c,-sq[i].d);
}
int main(){
n=read();
for(int i=1;i<=n;i++){
int a,b,c,d;
a=read();
b=read();
c=read();
d=read();
sq[i]=data(a,b,c,d,i);
number[++cnt]=c;
}
sort(number+1,number+1+cnt);
cnt=unique(number+1,number+1+cnt)-number;
for(int i=1;i<=n;i++){
sq[i].c=lower_bound(number+1,number+1+cnt,sq[i].c)-number;
mxX=max(mxX,sq[i].c);
}
sort(sq+1,sq+1+n,cmp);
solve(1,n);
int ans=0;
for(int i=1;i<=n;i++)
ans+=tag[i];
printf("%d",ans);
return 0;
}