【COGS2479】【HZOI2016】偏序(cdq套cdq)

C O G S COGS 炸了
没有传送门,没有题目
只有一个小菜鸡的做法和瞎**乱造的数据和暴力对拍


似乎不难?
参考 C a n d y Candy b l o g blog ,一看就懂
注意一下内层记录一个 f l a g flag 表示 b b 处于左边还是右边
因为内层 c d q cdq 中途会将顺序打乱

#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;
}

猜你喜欢

转载自blog.csdn.net/qq_42555009/article/details/88199744