题解:
预处理所有
bi
b
i
,每次询问相当于修改单点,修改相当于修改两个点。
用平衡树维护所有0的位置,有连续的则合并。 找的时候直接找最接近 i+2n i + 2 n 的地方。 为了细节少一点,找到了之后暴力往两边挪动几位取min就可以了。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
inline int rd() {
char ch=getchar(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=getchar();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=getchar();}
return i*f;
}
const int N=1e5+50,INF=0x3f3f3f3f;
typedef map <int,int> ::iterator it;
map <int,int> S;
int n,m,a[N],b[N],c[N];
inline int bef(int i) {return (i==1)?n:i-1;}
inline int nxt(int i) {return (i==n)?1:i+1;}
inline it bef(it p) {return --p;}
inline it nxt(it p) {return ++p;}
inline it getpos(int pos) {
it p=--S.upper_bound(pos);
if(p->first!=pos) {S[pos]=p->second; S[p->first]=pos-1; p=S.lower_bound(pos);}
if(p->second!=pos) {S[pos+1]=p->second; S[pos]=pos;}
return p;
}
inline void merge(int pos) {
it p=--S.upper_bound(pos);
while(bef(p)->first>0 && bef(p)->second==p->first-1) {p=bef(p); S[p->first]=pos; S.erase(nxt(p));}
while(nxt(p)->first<=n && nxt(p)->first==p->second+1) {S[p->first]=nxt(p)->second; S.erase(nxt(p));}
}
int nowval[N];
inline void modify(int pos,int x) {
if(nowval[pos]==0 && x) {
it p=getpos(pos);
S.erase(p);
} else if(nowval[pos] && !x) {
S[pos]=pos;
merge(pos);
} nowval[pos]=x;
}
inline bool in(int l,int r,int pos) {
if(l<=r) return l<=pos && pos<=r;
else return pos<=r || pos>=l;
}
inline int calc_dis(int l,int r,int pos) {
if(in(l,r,pos)) return 0;
return min(min(abs(pos-l),abs(pos-r)),min(n-abs(pos-l),n-abs(pos-r)));
}
inline int query(int pos) {
modify(pos,a[pos]); int ans=0;
if(S.size()==2) {modify(pos,b[pos]); return -1;}
it p=--S.upper_bound(pos+n/2>n?pos+n/2-n:pos+n/2);
if(p==--S.end()) --p;
if(p==S.begin()) ++p;
for(int i=1;i<=3;i++) p=(p==++S.begin() ? --(--S.end()):--p);
for(int i=1;i<=8;i++) {
int l=p->first,r=p->second;
if(l!=1 && r==n) {
it p2=++S.begin();
if(p2->first==1)r=p2->second;
}
if(l==1 && r!=n) {
it p2=--(--S.end());
if(p2->second==n) l=p2->first;
}
ans=max(ans,calc_dis(l,r,pos));
p=(p==--(--S.end())?++S.begin():++p);
}
modify(pos,b[pos]);
return ans;
}
int main() {
n=rd(), m=rd();
for(int i=1;i<=n;i++) a[i]=rd(), c[i]=(getchar()=='+')?0:1;
for(int i=1;i<=n;i++) {
if(c[i]==0) b[i]=(a[bef(i)]+a[i])%10;
else b[i]=(a[bef(i)]*a[i])%10;
}
S[0]=0; S[n+1]=n+1;
for(int i=1;i<=n;i++)
nowval[i]=1,modify(i,b[i]);
for(int i=1;i<=m;i++) {
int op=rd(), x=rd()+1;
if(op==2) printf("%d\n",query(x));
else {
a[x]=rd(), c[x]=(getchar()=='+')?0:1;
if(c[x]==0) b[x]=(a[bef(x)]+a[x])%10;
else b[x]=(a[bef(x)]*a[x])%10;
if(c[nxt(x)]==0) b[nxt(x)]=(a[x]+a[nxt(x)])%10;
else b[nxt(x)]=(a[x]*a[nxt(x)])%10;
modify(x,b[x]); modify(nxt(x),b[nxt(x)]);
}
}
}