[ABC341E] Alternating String

在我的代码中,下标一般从 0 开始,大部分函数/类的方法最寻左闭右开原则。


我们维护一个布尔数组 表示 是否相等,相等为 ,不相等为 。至于 的首项,他对答案不会产生影响,设置成什么都无所谓。

对于操作二,显然 中区间 元素全部与它前面的值不相同时,字符串是“好的”。只需要判读 中这一段区间和是否为 就好。

对于操作一,可以发现: 内部的元素与其前继元素是否相等不会因为区间反转而改变。我们要改变的只有

单点修改、区间求和……我会了,树状数组/线段树!

#include<bits/extc++.h>
using namespace std;
namespace pbds=__gnu_pbds;
using ui=unsigned int;
using uli=unsigned long long int;
using li=long long int;
template<typename T> class FenwickTree{
    vector<T> tree;
    // To get sum in interval [0,p) (no p).
    T prefix_sum(size_t p){
        T res=0;
        for (--p;p<tree.size();--(p&=(p+1))) res+=tree[p];
        return res;
    }
public:
    FenwickTree(size_t n):tree(n){}
    void add(size_t p,T const& val){
        for (;p<tree.size();p|=p+1) tree[p]+=val;
    }
    T get_sum(size_t l,size_t r){
        return prefix_sum(r)-prefix_sum(l);
    }
    T get(size_t p){return get_sum(p,p+1);}
};
int main(void){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    size_t n,m;cin>>n>>m;
    vector<bool> a(n);
    for (vector<bool>::reference i:a){char c;cin>>c;i=c=='1';}
    FenwickTree<ui> same_as_prev(n);
    for (size_t i=1;i<n;++i) same_as_prev.add(i,a[i]==a[i-1]);
    while (m--){
        char op;size_t l,r;cin>>op>>l>>r;
        if (op=='1')
            same_as_prev.add(l-1,same_as_prev.get(l-1)?-1:1),
            same_as_prev.add(r,same_as_prev.get(r)?-1:1);
        else if (op=='2')
            cout<<(same_as_prev.get_sum(l,r)?"No\n":"Yes\n");
        else throw;
    }
    return 0;
}
posted @ 2024-02-19 19:30  MrPython  阅读(3)  评论(0)    收藏  举报  来源