ABC415 F 分块玄关求调
  • 板块题目总版
  • 楼主Lawrenceling
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/7/19 23:26
  • 上次更新2025/7/20 15:11:34
查看原帖
ABC415 F 分块玄关求调
1026751
Lawrenceling楼主2025/7/19 23:26

AC 28 个点,具体可见这里

思路是维护每个块的单块答案,向左/向右能延伸到的最远距离,具体见代码,疑似 query() 出锅。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=5e5+10;
int q,n,t,a[N];
int L[N],R[N],pos[N];
int mx[N],lft[N],rgt[N];

inline void Init(int n)
{
	t=sqrt(n);
	for(int i=1;i<=t;++i)
		L[i]=(i-1)*t+1,R[i]=i*t; 
	if(R[t]<n)R[t]=n;
	for(int i=1;i<=t;++i)
	{
		int sum=1;
		for(int j=L[i];j<=R[i];++j)
		{
			if(j>L[i]&&a[j]==a[j-1])sum++;
			else sum=1;
			mx[i]=max(mx[i],sum);
			pos[j]=i;
		}
		for(int j=L[i];j<=R[i];++j)
			if(a[j]==a[L[i]])lft[i]=j;
			else break;
		for(int j=R[i];j>=L[i];--j)
			if(a[j]==a[R[i]])rgt[i]=j;
			else break;
	}		
}
inline void Update(int x,int y)
{
	int p=pos[x],sum=1;
	a[x]=y;mx[p]=1;
	for(int i=L[p];i<=R[p];++i)
	{
		if(i>L[p]&&a[i]==a[i-1])sum++;
		else sum=1;
		mx[p]=max(mx[p],sum);
	}
	for(int j=L[p];j<=R[p];++j)
		if(a[j]==a[L[p]])lft[p]=j;
		else break;
	for(int j=R[p];j>=L[p];--j)
		if(a[j]==a[R[p]])rgt[p]=j;
		else break;
}  
inline int Query(int l,int r)
{
	int pl=pos[l],pr=pos[r];
	if(pl==pr)
	{
		int sum=1,maxx=1;
		for(int i=l;i<=r;++i)
		{
			if(i>l&&a[i]==a[i-1])sum++;
			else sum=1;
			maxx=max(maxx,sum);
		}
		return maxx;
	}
	int sum=1,maxx=1;
	for(int i=l;i<=R[pl];++i)
	{
		if(i>l&&a[i]==a[i-1])sum++;
		else sum=1;
		maxx=max(maxx,sum);
	}
	sum=1;
	for(int i=L[pr];i<=r;++i)
	{
		if(i>L[pr]&&a[i]==a[i-1])sum++;
		else sum=1;
		maxx=max(maxx,sum);
	}
	sum=R[pl]-max(rgt[pl],l)+1;
	for(int i=pl+1;i<=pr;++i)
	{
		if(i!=pr)maxx=max(maxx,mx[i]);
		maxx=max(sum,maxx);
		if(a[L[i]]==a[R[i-1]])
		{
			sum+=min(lft[i],r)-L[i]+1;
			maxx=max(maxx,sum);
			if(lft[i]==R[i])continue;
		}
		sum=R[i]-rgt[i]+1;
		maxx=max(sum,maxx);
	}
	return maxx;
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	
	string s;
	cin>>n>>q>>s;
	for(int i=0;i<n;++i)a[i+1]=s[i]-'a'+1;
	Init(n);
	while(q--)
	{
		int opt,x;
		cin>>opt>>x;
		if(opt==1)
		{
			char y;cin>>y;
			Update(x,y-'a'+1);
		}
		else
		{
			int y;cin>>y;
			cout<<Query(x,y)<<'\n';
		}
	}
	return 0;
}
2025/7/19 23:26
加载中...