[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;
}
浙公网安备 33010602011771号