补题计划

link

第一次认真打月赛竟然还做出来了一道不简单的题(虽然只是Div2的T3),很开心。但赛后只评了个蓝。靠。呜呜呜。

询问足够水,那个 \(l+h\le 5\) 着实是大大的良心,枚举喜欢的题,结合讨厌的题就可以找出左右端点的范围,然后贪心取最大最小值(反正二者的选择又互不影响)相减就可以得到最大区间和,这部分用线段树维护即可。于是问题变成了如何快速地维护和重建线段树。由于每次操作的区间长度不变而且没有强制在线(感谢出题人),于是想到离线,可以以值域为数轴想象每次修改,然后会发现假如把修改排序然后顺次滑动,每个值都只会被端点经过常数次,于是线段树重构就转化成了多次单点修改,然后就是惯常操作了,离线,排序,挪动四个指针(为啥那么那么多啊啊啊),更新线段树,查询即可。由于题目设定比较复杂所以整个过程有点繁琐,但好在我运气比较好一发就过了,希望这种好运气可以一直持续下去。

丑陋的考场代码:

#include<bits/stdc++.h>
//#define feyn
using namespace std;
const int N=100010;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}
inline int max(int s1,int s2){
	return s1<s2?s2:s1;
}
inline int min(int s1,int s2){
	return s1<s2?s1:s2;
}

int m,n,w,len,dis,dataa,datab,a[N];

#define lc (wh<<1)
#define rc (wh<<1|1)
#define mid (t[wh].l+t[wh].r>>1)
struct node{
	int l,r,lazy,maxn,minn;
}t[N<<2];
inline int work_data(int wh,int ww){
	int cc=wh-ww;cc=cc<0?-cc:cc;
	if(cc<=len)return dataa;
	if(cc>dis)return datab;
	return 0;
}
inline void pushup(int wh){
	t[wh].maxn=max(t[lc].maxn,t[rc].maxn);
	t[wh].minn=min(t[lc].minn,t[rc].minn);
}
inline void pushnow(int wh,int val){
	t[wh].lazy+=val;
	t[wh].maxn+=val;
	t[wh].minn+=val;
}
inline void pushdown(int wh){
	if(t[wh].lazy){
		pushnow(lc,t[wh].lazy);
		pushnow(rc,t[wh].lazy);
		t[wh].lazy=0;
	}
}
int fir_data[N];
inline void build(int wh,int l,int r,int fir_w){
	t[wh].l=l,t[wh].r=r;
	if(wh==1)for(int i=1;i<=m;i++)fir_data[i]=fir_data[i-1]+work_data(a[i],fir_w);
	if(l==r){t[wh].minn=t[wh].maxn=fir_data[l];return;}
	build(lc,l,mid,fir_w);
	build(rc,mid+1,r,fir_w);
	pushup(wh);
}
inline void change(int wh,int wl,int wr,int val){
	if(wl<=t[wh].l&&t[wh].r<=wr){pushnow(wh,val);return;}
	pushdown(wh);
	if(wl<=mid)change(lc,wl,wr,val);
	if(wr>mid)change(rc,wl,wr,val);
	pushup(wh);
}
inline int work_max(int wh,int wl,int wr){
	if(wl<=t[wh].l&&t[wh].r<=wr)return t[wh].maxn;
	int an=-1e9;pushdown(wh);
	if(wl<=mid)an=max(an,work_max(lc,wl,wr));
	if(wr>mid)an=max(an,work_max(rc,wl,wr));
	return an;
}
inline int work_min(int wh,int wl,int wr){
	if(wl<=t[wh].l&&t[wh].r<=wr)return t[wh].minn;
	int an=1e9;pushdown(wh);
	if(wl<=mid)an=min(an,work_min(lc,wl,wr));
	if(wr>mid)an=min(an,work_min(rc,wl,wr));
	return an;
}
#undef lc
#undef rc
#undef mid

struct ask{int na,nb,a[6],b[6],ans;};
vector<ask>s[N];
struct data{int pl,data;}q[N],b[N];
inline bool cmp(data s1,data s2){
	return s1.data<s2.data;
}

signed main(){
	
	#ifdef feyn
	freopen("in.txt","r",stdin);
	#endif
	
	read(m);read(m);read(n);read(w);read(len);read(dis);read(dataa);read(datab);
	for(int i=1;i<=m;i++){read(a[i]);b[i]=(data){i,a[i]};}
	int ntime=1;q[ntime]=(data){ntime,w};
	while(n--){
		int op,in;read(op);
		if(op==1){
			ask now;read(now.na);read(now.nb);
			for(int i=1;i<=now.na;i++)read(now.a[i]);
			for(int i=1;i<=now.nb;i++)read(now.b[i]);
			s[ntime].push_back(now);
		}
		else{
			ntime++;read(in);
			q[ntime]=(data){ntime,in};
		}
	}
	sort(b+1,b+m+1,cmp);
	sort(q+1,q+ntime+1,cmp);
	build(1,0,m,q[1].data);
	int al=1,ar=1,bl=1,br=1;
	while(al<=m&&b[al].data<q[1].data-dis)al++;
	while(ar<=m&&b[ar].data<q[1].data-len)ar++;
	while(bl<=m&&b[bl].data<=q[1].data+len)bl++;
	while(br<=m&&b[br].data<=q[1].data+dis)br++;
	for(int i=1;i<=ntime;i++){
		//printf("now:%d\n",q[i].data);
		while(br<=m&&b[br].data<=q[i].data+dis)change(1,b[br++].pl,m,-datab);
		while(bl<=m&&b[bl].data<=q[i].data+len)change(1,b[bl++].pl,m,dataa);
		while(ar<=m&&b[ar].data<q[i].data-len)change(1,b[ar++].pl,m,-dataa);
		while(al<=m&&b[al].data<q[i].data-dis)change(1,b[al++].pl,m,datab);
		int t=q[i].pl;
		for(int j=0;j<s[t].size();j++){
			ask now=s[t][j];int ans=-1e9;
			for(int i=1;i<=now.na;i++){
				int l=1,r=m;
				for(int j=1;j<=now.nb;j++){if(now.b[j]>now.a[i])break;l=now.b[j]+1;}
				for(int j=now.nb;j;j--){if(now.b[j]<now.a[i])break;r=now.b[j]-1;}
				ans=max(ans,work_max(1,now.a[i],r)-work_min(1,l-1,now.a[i]-1));
			}
			s[t][j].ans=ans;
		}
	}
	for(int i=1;i<=ntime;i++){
		for(int j=0;j<s[i].size();j++){
			printf("%d\n",s[i][j].ans);
		}
	}
	
	return 0;
}
posted @ 2022-07-31 18:02  Feyn618  阅读(25)  评论(0编辑  收藏  举报