听取WA声一片(有一定量注释)
查看原帖
听取WA声一片(有一定量注释)
1261547
belif__kibo楼主2024/9/17 22:26

如图所示

#include<bits/stdc++.h>
#define int long long int
using namespace std;
int n,m,s[100010],id[100010],maxn[1000],add[1000],del[1000],len;
//s为原数组,id[x]记录x所在块,maxn[x]记录块x内最大元素的下标,add[x]和del[x]由s[i]=s[i]+i*t-(l-1)*t可得
signed main()
{
	scanf("%lld%lld",&n,&m);
	len=sqrt(n);
	for(int i=1;i<=n;i++) id[i]=(i-1)/len+1,maxn[id[i]]=(id[i]-1)*len+1;//分块,初始化maxn
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&s[i]);
		if(s[i]>s[maxn[id[i]]]) maxn[id[i]]=i;
	}
	while(m--)
	{
		int type;
		scanf("%lld",&type);
		if(type==1)
		{
			int l,r,a,b,ans=0,base=s[1]+add[1]-del[1];
			scanf("%lld%lld",&l,&r);
			a=id[l],b=id[r];
			if(a==b)
			{
				for(int i=l;i<=r;i++) ans=max(ans,s[i]+i*add[a]-del[a]-base);
				printf("%lld\n",ans);
				continue;
			}
			for(int i=l;id[i]==a;i++) ans=max(ans,s[i]+i*add[a]-del[a]-base);
			for(int i=r;id[i]==b;i--) ans=max(ans,s[i]+i*add[b]-del[b]-base);
			for(int i=a+1;i<b;i++) ans=max(ans,s[maxn[i]]+maxn[i]*add[i]-del[i]-base);
			printf("%lld\n",ans);
			continue;
		}
		if(type==2)//暴力重构a,b所在块
		{
			int a,b;
			scanf("%lld%lld",&a,&b);
			for(int i=(id[a]-1)*len+1;i<=min(id[a]*len,n);i++) s[i]=s[i]+i*add[id[i]]-del[id[i]];
			for(int i=(id[b]-1)*len+1;i<=min(id[b]*len,n);i++) s[i]=s[i]+i*add[id[i]]-del[id[i]];
			add[id[a]]=0,del[id[a]]=0,add[id[b]]=0,del[id[b]]=0;
			maxn[id[a]]=(id[a]-1)*len+1,maxn[id[b]]=(id[b]-1)*len+1;
			s[a]=s[a]^s[b];s[b]=s[a]^s[b];s[a]=s[a]^s[b];
			for(int i=(id[a]-1)*len+1;i<=min(id[a]*len,n);i++) if(s[i]>s[maxn[id[a]]]) maxn[id[a]]=i;
			for(int i=(id[b]-1)*len+1;i<=min(id[b]*len,n);i++) if(s[i]>s[maxn[id[b]]]) maxn[id[b]]=i;
			continue;
		}
		if(type==3)//暴力处理散块,处理整块时认为maxn指针只会向右移
		{
			int l,r,a,b,k;
			scanf("%lld%lld%lld",&l,&r,&k);
			a=id[l],b=id[r];
			if(a==b)
			{
				for(int i=l,base=k;i<=r;i++,base+=k) s[i]+=base;
				for(int i=l;i<=r;i++) if(s[i]+i*add[a]-del[a]>s[maxn[a]]+maxn[a]*add[a]-del[a]) maxn[a]=i;
				continue;
			}
			for(int i=l,base=k;id[i]==a;i++,base+=k) s[i]+=base;
			for(int i=l;id[i]==a;i++) if(s[i]+i*add[a]-del[a]>s[maxn[a]]+maxn[a]*add[a]-del[a]) maxn[a]=i;
			for(int i=r,base=(r-l+1)*k;id[i]==b;i--,base-=k) s[i]+=base;
			for(int i=r;id[i]==b;i--) if(s[i]+i*add[b]-del[b]>s[maxn[b]]+maxn[b]*add[b]-del[b]) maxn[b]=i;
			for(int i=a+1;i<b;i++)
			{
				add[i]+=k;
				del[i]+=(l-1)*k;
				for(int j=maxn[i];id[j]==i;j++) if(s[j]+j*add[i]-del[i]>s[maxn[i]]+maxn[i]*add[i]-del[i]) maxn[i]=j;
			}
		}
	}
}
2024/9/17 22:26
加载中...