题解
对于区间全部元素 \(+x\)
等价于对 差分数组的 \(d[l]+=x\),\(d[r+1]-=x\)
也就是只修改了两个点
如果存在回文串,要么是 \(s[i]==s[i-1]\) 要么是 \(s[i]==s[i-2]\) ,所以我们可以用 \(set\) 维护23回文串的右端点
code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
void solve()
{
int n,q;
cin>>n>>q;
string s;
cin>>s;
s=' '+s;
vector<int> d(n+5);
for(int i=1;i<=n;i++) d[i]=s[i];
for(int i=n;i>1;i--) d[i]-=d[i-1];
set<int> bad2,bad3;
auto upd=[&](int i)
{
bad2.erase(i);
bad3.erase(i);
if(i<0||i>n) return;
if(d[i]%26==0) bad2.insert(i);
if(i>1&&(d[i]+d[i-1])%26==0) bad3.insert(i);
};
for(int i=1;i<=n;i++) upd(i);
while(q--)
{
int op;
cin>>op;
if(op==1)
{
int l,r,x;
cin>>l>>r>>x;
d[l]+=x;
d[l]%=26;
d[r+1]-=x;
d[r+1]%=26;
for(int i:{0,1})
{
upd(l+i);
upd(r+1+i);
}
}
else
{
int l,r;
cin>>l>>r;
auto it2=bad2.insert(r+1).first,it3=bad3.insert(r+1).first;
bool flag=0;
if(it2!=bad2.begin()&&*prev(it2)-1>=l) flag=1;
if(it3!=bad3.begin()&&*prev(it3)-2>=l) flag=1;
if(flag) cout<<"no\n";
else cout<<"yes\n";
upd(*it2);
upd(*it3);
}
}
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t=1;
cin>>t;
while(t--) solve();
return 0;
}
标签:insert,26,bad3,String,int,cin,Mysterious,Anya,bad2
From: https://www.cnblogs.com/pure4knowledge/p/18302953