CDQ分治求调。。。
查看原帖
CDQ分治求调。。。
1423269
ini_____楼主2025/1/12 16:40

自闭了,调了快两个小时,连样例都过不了。。。

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+100;
int a[N],b[N];
int premax[N],premin[N];
int id[N];
int n;
long long res=0; 
vector<int> q[2*N];
void cdq(int l,int r){
	if(l==r){
		res++;
		return;
	}
	int mid=(l+r)>>1;
	cdq(l,mid);
	cdq(mid+1,r); 
	for(int i=mid;i>=l;i--){
		premax[i]=a[i];
		if(i<mid)premax[i]=max(premax[i+1],premax[i]);
		premin[i]=a[i];
		if(i<mid)premin[i]=min(premin[i+1],premin[i]);
	}
	for(int i=mid+1;i<=r;i++){
		premax[i]=a[i];
		if(i>mid+1)premax[i]=max(premax[i-1],premax[i]);
		premin[i]=a[i];
		if(i>mid+1)premin[i]=min(premin[i-1],premin[i]);
	}
	//分类讨论max,min在哪个区间
	//max\in l,min \in l
	for(int i=l;i<=mid;i++){
		int j=premax[i]-premin[i]+i;
		if(j<=r&&j>mid&&premax[j]<premax[i]&&premin[j]>premin[i])res++;
	}
	//max\in r,min\in r
	for(int i=mid+1;i<=r;i++){
		int j=premin[i]-premax[i]+i;
		if(premax[j]<premax[i] and premin[j]>premin[i] and j<=mid and j>=l)res++;
	}
	//max\in r ,min\in l
	
	for(int i=l;i<=mid;i++)q[premin[i]-i+N].push_back(i);
	for(int i=mid+1;i<=r;i++){
		int pos=premax[i]-i+N;
		if(!q[pos].size())continue;
		int L=0,R=q[pos].size()-1;
		if(premax[q[pos][R]]>=premax[i] or premin[q[pos][L]]>=premin[i])continue;
		while(L<R){
			int mid=(L+R)>>1;
			if(premax[q[pos][mid]]<premax[i])R=mid;
			else L=mid+1;
		}
		int _r=R;
		L=0,R=q[pos].size()-1;
		while(L<R){
			int mid=(L+R+1)>>1;
			if(premin[q[pos][mid]]<premin[i])L=mid;
			else R=mid-1;
		}
		int _l=R;
		if(_r>=_l)res+=(long long)(_r-_l+1);
	}
	for(int i=l;i<=mid;i++)q[premin[i]-i+N].clear();
	//max\in l min\in r
	for(int i=mid+1;i<=r;i++)q[premin[i]+i].push_back(i);
	for(int i=l;i<=mid;i++){
		int pos=premax[i]+i;
		if(!q[pos].size())continue;
		int L=0,R=q[pos].size()-1;
		if(premax[q[pos][L]]>=premax[i] or premin[q[pos][R]]>=premin[i])continue;
		while(L<R){
			int mid=(L+R+1)>>1;
			if(premax[q[pos][mid]]<premax[i])L=mid;
			else R=mid-1;
		}
		int _r=R;
		L=0,R=q[pos].size()-1;
		while(L<R){
			int mid=(L+R)>>1;
			if(premin[q[pos][mid]]<premin[i])R=mid;
			else L=mid+1;
		}
		int _l=R;
		if(_r>=_l)res+=(long long)(_r-_l+1);
	}
	for(int i=mid+1;i<=r;i++)q[premin[i]+i].clear();
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i]>>b[i],id[a[i]]=b[i];
	for(int i=1;i<=n;i++)a[i]=id[i];
	cdq(1,n);
	cout<<res;
	return 0;
}

2025/1/12 16:40
加载中...