L-最长连续相同字符,分段统计
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
int a[400][400];
int b[400], c[400], a1[400];
int n,n1,last,ans,ansi,ans1=0,ansi1=0;
char str[101000];
void count(int x){
int j,i=x*n1,y=min(i+n1-1,n-1);
a1[x] = 0;b[x] = 0;c[x] =0;
while(i<=y){
j=i;
while(j<=y && str[j] ==str[i]) ++j;
a[x][a1[x]] =j-i;
++a1[x];
if (j-i>b[x]){
b[x] = j-i;c[x] = i;
}
i=j;
}
return;
}
void count1(int l, int r){
int i=l,j;
while(i<=r){
j=i;
while(j<=r && str[j] ==str[i]) ++j;
last = j-i;
if (last>ans){
ans = last;ansi=i;
}
i=j;
}
}
int count2(int l, int r){
int i=r,j, last1;
last1 = 0;ans1=0,ansi1=0;
while(i>=l){
j=i;
while(j>=l && str[j] ==str[i]) --j;
last1 = i-j;
if (last1>=ans1){
ans1 = last1;ansi1=j+1;
}
i=j;
}
return last1;
}
void my_ans(){
int i,j,m,k,op,l,r,mi,ma,mid,x,y,last1;
cin>>n>>m;
char ch;
n1 = (int)sqrt(n)+1;
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
for(i=0;i<n;++i) cin>>str[i];
for(i=0;i<n1;++i) count(i);
while(m>0){
--m;cin>>op;
if (op==1){
cin>>l>>r;--l;--r;
ans =1;ansi=l;last=0;
if (r-l<8000){
count1(l, r);
}else{
count1(l, (l/n1)*n1+n1-1);
i=l/n1+1;
while(i<r/n1){
if (str[i*n1] == str[i*n1-1]){
if (last+a[i][0]>ans){
ans = last+a[i][0];ansi = i*n1-last;
}
last += a[i][0];
}
if (a1[i] >1) last = a[i][a1[i]-1];
if (b[i]>ans){
ans = b[i];ansi=c[i];
}
++i;
}
last1 = count2((r/n1)* n1, r);
if (str[(r/n1)* n1] == str[(r/n1)* n1-1]){
if (last1+last>ans){
ans = last1+last;ansi = (r/n1)* n1 -last;
}
}
if (ans1>ans){
ans = ans1;ansi=ansi1;
}
}
cout<<ansi+1<<" "<<ansi+ans<<endl;
}else{
cin>>x>>ch;--x;
str[x] = ch;
count(x/n1);
}
}
return;
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t=1,i,j;
//cin>>t;
while(t>0){
--t;my_ans();
}
return 0;
}
// 64 位输出请用 printf("%lld")