F
如果我们每次操作都去检查 l-r 内的数字,时间复杂度是O(n2) 我没有去尝试
换一种方式
假如操作的是 'A' 那原本 位置上的 1-0,1-1 都不会发生改变,能改变的只有 0-1 变成 1-1 0-0 变成 1-0
所以我们去记住字符串中哪些位置是0即可
每次我们找到在l,r区间内的0,进行操作变化
操作的时间复杂变是 O(n), 查找 的复杂度是 O(lgn)
总时间就是 O(n)+ O(qlgn)
#pragma GCC optimize("O2,unroll-loops") #pragma GCC target("avx,avx2") // #include "atcoder/all" #include <bits/stdc++.h> using namespace std; using ll = long long; const int MOD1000000007 = 1000000007; const int MOD998244353 = 998244353; const double PI = 3.14159265358979323846264338327950288; const int N = 2e5+5; void solve() { int n; cin>>n; string s1,s2; cin>>s1>>s2; set<int> st1,st2; int ans = 0; for(int i = 0;i<n;i++){ if(s1[i]=='1' && s2[i]=='1'){ ans+=1; } if(s1[i]=='0') st1.insert(i); if(s2[i]=='0') st2.insert(i); } int op; cin>>op; while(op--){ string s; int l,r; cin>>s>>l>>r; l--,r--; if(s[0]=='A'){ auto it1 = st1.lower_bound(l); auto it2 = st1.lower_bound(r+1); for(auto it = it1;it!=it2;it++){ int p = *it; if(s2[p]=='1') ans+=1; s1[p] = '1'; } st1.erase(it1,it2); }else{ auto it1 = st2.lower_bound(l); auto it2 = st2.lower_bound(r+1); for(auto it = it1;it!=it2;it++){ int p = *it; if(s1[p]=='1') ans+=1; s2[p] = '1'; } st2.erase(it1,it2); } cout<<ans<<endl; } } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(0); #ifdef LOCAL freopen("input.txt", "r", stdin); #endif // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int testcase = 1; // cin >> testcase; // scanf("%d\n", &testcase); while (testcase--) solve(); return 0; }