ROI2017 學習軌跡(轉化,線段樹,單調棧,性質挖掘)

題目
在這裏插入圖片描述
在這裏插入圖片描述
AC Code\mathcal AC \ Code

#include<bits/stdc++.h>
#define maxn 500005
#define LL long long
#define lc u<<1
#define rc lc|1
#define inf 1e17
using namespace std;

int n,m,a[maxn],ra[maxn<<1],b[maxn];
LL x[maxn],y[maxn];
map<LL,int>mAp;

int cnt;
struct block{
	int xl,xr,yl,yr;
	bool operator <(const block &B)const{
		return xl < B.xl;
	}
}B[maxn];

int mxp[maxn<<2];
LL mx[maxn<<2],ad[maxn<<2];

void upd(int u){
	if(mx[lc] > mx[rc]) mx[u] = mx[lc] , mxp[u] = mxp[lc];
	else mx[u] = mx[rc] , mxp[u] = mxp[rc];
}
void dtp(int u,LL v){ ad[u] += v;mx[u] += v; }
void dt(int u){ 
	if(ad[u]) dtp(lc,ad[u]),dtp(rc,ad[u]),ad[u]=0;
} 
void Build(int u,int l,int r){
	ad[u] = 0;
	if(l==r) return (void)(mx[u]=y[m]-x[l],mxp[u]=l,ad[u]=0);
	int m=l+r>>1;
	Build(lc,l,m),Build(rc,m+1,r);
	upd(u);
}
void add(int u,int l,int r,int ql,int qr,LL v){
	if(ql>r||l>qr) return;
	if(ql<=l&&r<=qr) return (void)(dtp(u,v));
	int m=l+r>>1;dt(u);
	add(lc,l,m,ql,qr,v),add(rc,m+1,r,ql,qr,v);
	upd(u);
}

pair<int,LL>st[2][maxn];
int qr[2],l1,r1,l2,r2;
LL ans;

LL ser(int t,int x){
	int l=1,r=qr[t]+1,mid;
	for(;l<r;){
		mid=l+r>>1;
		if(st[t][mid].first > x) r = mid;
		else l = mid + 1;
	}
	if(l > qr[t]) return y[m]>>1;
	return st[t][l].second;
}

void Solve(bool tf){
	sort(B+1,B+1+cnt);
	Build(1,0,n);
	qr[0] = qr[1] = 0;
	st[0][++qr[0]] = make_pair(0,-inf);
	st[1][++qr[1]] = make_pair(0,-inf);
	for(int i=1;i<=cnt;i++){
		if(mx[1] + x[B[i].xl] > ans){
			ans = mx[1] + x[B[i].xl];
			l1=mxp[1],r1=B[i].xl;
			l2=mAp[(y[m]>>1)-ser(1,l1)],r2=mAp[(y[m]>>1)+ser(0,l1)];
			if(tf) swap(l1,l2),swap(r1,r2);
		}
		if(y[B[i].yr] > (y[m]>>1)){
			pair<int,LL>t(B[i].xr,y[B[i].yl]-(y[m]>>1));
			if(t.second < 0) t.second = -inf;
			add(1,0,n,st[0][qr[0]].first,t.first-1,-y[m]>>1);
			for(;qr[0] && st[0][qr[0]].second > t.second;){
				pair<int,LL>p = st[0][qr[0]--];
				add(1,0,n,st[0][qr[0]].first,p.first-1,-p.second);
			}
			add(1,0,n,st[0][qr[0]].first,t.first-1,t.second);
			st[0][++qr[0]] = t;
		}
		if(y[B[i].yl] < (y[m]>>1)){
			pair<int,LL>t(B[i].xr,-y[B[i].yr]+(y[m]>>1));
			if(t.second < 0) t.second = -inf;
			add(1,0,n,st[1][qr[1]].first,t.first-1,-y[m]>>1);
			for(;qr[1] && st[1][qr[1]].second > t.second;){
				pair<int,LL>p = st[1][qr[1]--];
				add(1,0,n,st[1][qr[1]].first,p.first-1,-p.second);
			}
			add(1,0,n,st[1][qr[1]].first,t.first-1,t.second);
			st[1][++qr[1]] = t;
		}
	}
	if(mx[1] + x[n] > ans){
		ans = x[n] + mx[1];
		l1=mxp[1],r1=n;
		l2=mAp[(y[m]>>1)-ser(1,l1)],r2=mAp[(y[m]>>1)+ser(0,l1)];
		if(tf) swap(l1,l2),swap(r1,r2);
	}
}

int main(){
	
//	freopen("1.in","r",stdin);
	
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),ra[a[i]]=i;
	for(int i=1;i<=n;i++) scanf("%lld",&x[i]),x[i]<<=1,x[i]+=x[i-1];
	for(int i=1;i<=m;i++) scanf("%d",&b[i]);
	for(int i=1;i<=m;i++){
		scanf("%d",&y[i]),y[i]<<=1,y[i]+=y[i-1];
		mAp[y[i]] = i;
		if(ra[b[i]]){
			int u=ra[b[i]];
			B[++cnt].xl=u-1,B[cnt].xr=u;
			B[cnt].yl=i-1,B[cnt].yr=i;
		}
	}
	
	Solve(0);
	swap(x,y),swap(n,m);
	mAp.clear();
	for(int i=1;i<=m;i++) mAp[y[i]] = i;
	for(int i=1;i<=cnt;i++) swap(B[i].xl,B[i].yl),swap(B[i].xr,B[i].yr);
	Solve(1);
	printf("%lld\n",ans/2);
	if(l1==r1) l1=-1,r1=0;
	if(l2==r2) l2=-1,r2=0;
	printf("%d %d\n",l1+1,r1);
	printf("%d %d\n",l2+1,r2);
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章