G. Anya and the Mysterious String

原题链接

题解

对于区间全部元素 \(+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;
}


posted @ 2024-07-15 13:08  纯粹的  阅读(11)  评论(0)    收藏  举报