炸了
没有传送门,没有题目
只有一个小菜鸡的做法和瞎**乱造的数据和暴力对拍
似乎不难?
参考的,一看就懂
注意一下内层记录一个表示处于左边还是右边
因为内层中途会将顺序打乱
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();
int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
return res;
}
char x;
const int N=50005;
struct point{
int a,b,c,d;
bool flag;
friend inline bool operator <(const point &a,const point &b){
return a.a<b.a;
}
}q[N],q1[N],q2[N];
int tr[N],n;
inline int lowbit(int x){
return x&(-x);
}
inline int query(int p,int res=0){
for(;p;p-=lowbit(p))res+=tr[p];return res;
}
inline void update(int p,int k){
for(;p<=n;p+=lowbit(p))tr[p]+=k;
}
int ans;
char y;
inline void cdq2(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
cdq2(l,mid),cdq2(mid+1,r);
int i=l,cnt=l-1;
for(int j=mid+1;j<=r||i<=mid;){
if(j>r||(i<=mid&&q1[i].c<q1[j].c)){
if(q1[i].flag)update(q1[i].d,1);
q2[++cnt]=q1[i++];
}
else{
if(!q1[j].flag)ans+=query(q1[j].d);
q2[++cnt]=q1[j++];
}
}
for(int i=l;i<=mid;i++)if(q1[i].flag)update(q1[i].d,-1);
for(int i=l;i<=r;i++)q1[i]=q2[i];
}
inline void cdq1(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
cdq1(l,mid),cdq1(mid+1,r);
int i=l,cnt=l-1;
for(int j=mid+1;i<=mid||j<=r;){
if(j>r||(i<=mid&&q[i].b<q[j].b))(q1[++cnt]=q[i++]).flag=1;
else (q1[++cnt]=q[j++]).flag=0;
}
for(int i=l;i<=r;i++)q[i]=q1[i];
cdq2(l,r);
}
signed main(){
n=read();
for(int i=1;i<=n;i++)q[i].a=read();
for(int i=1;i<=n;i++)q[i].b=read();
for(int i=1;i<=n;i++)q[i].c=read();
for(int i=1;i<=n;i++)q[i].d=read();
sort(q+1,q+n+1);
cdq1(1,n);
cout<<ans;
}