Problem:
Problem E
  Black or White
Here lies a row of a number of bricks each painted either black or white. With a single stroke of your brush, you can overpaint a part of the row of bricks at once with either black or white paint. Using white paint, all the black bricks in the painted part become white while originally white bricks remain white; with black paint, white bricks become black and black ones remain black. The number of bricks painted in one stroke, however, is limited because your brush cannot hold too much paint at a time. For each brush stroke, you can paint any part of the row with any number of bricks up to the limit.
In the first case of the sample input, the initial colors of four bricks are black, white, white, and black. You can repaint them to white, black, black, and white with two strokes: the first stroke paints all four bricks white and the second stroke paints two bricks in the middle black.
Your task is to calculate the minimum number of brush strokes needed to change the brick colors as specified. Never mind the cost of the paints.
Input
The input consists of a single test case formatted as follows.
$n$ $k$
$s$
$t$
The first line contains two integers $n$ and $k$ ($1 \leq k \leq n \leq 500 000$). $n$ is the number of bricks in the row and $k$ is the maximum number of bricks painted in a single stroke. The second line contains a string $s$ of $n$ characters, which indicates the initial colors of the bricks. The third line contains another string $t$ of $n$ characters, which indicates the desired colors of the bricks. All the characters in both s and t are either
B
or
W
meaning black and white, respectively.
Output
Output the minimum number of brush strokes required to repaint the bricks into the desired colors.
Sample Input 1
4 4
BWWB
WBBW
Sample Output 1
2
Sample Input 2
4 3
BWWB
WBBW
Sample Output 2
3
Sample Input 3
4 3
BWWW
BWWW
Sample Output 3
0
Sample Input 4
7 1
BBWBWBW
WBBWWBB
Sample Output 4
4

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ull unsigned long long
#define ld long double
#define pb push_back
#define mkp make_pair
#define fi first
#define se second
#define pii pair<int, int>
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define rep(i, l, r) for (int i = (l); i < (r); ++i)
#define per(i, l, r) for (int i = (r)-1; i >= (l); --i)
#define INF 0x3f3f3f3f
#define LINF (ll)4e18
#define EPS 1e-9
#define PI acos(-1)
#define fopen_in(f)  freopen(f, "r", stdin)
#define fopen_out(f) freopen(f, "w", stdout)
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl

const int maxn = 500005;
int dp[maxn], a[maxn], b[maxn];
struct Seg {
    int n;
    vector<int> st, lazy;
    Seg () = default;
    Seg(int _n) : n(_n) {
        st.resize(4 * n + 5, INF);
        lazy.resize(4 * n + 5, 0);
    }
    void down (int id) {
        if(!lazy[id]) return;
        st[2 * id] += lazy[id];
        st[2 * id + 1] += lazy[id];
        lazy[2 * id] += lazy[id];
        lazy[2 * id + 1] += lazy[id];
        lazy[id] = 0;
    }
    void update (int id, int l, int r, int u, int v, int val) {
        if(l > v || r < u) return;
        if(l >= u && r <= v) {
            st[id] += val;
            lazy[id] += val;
            return;
        }
        int mid = l + r >> 1;
        down(id);
        update(2 * id, l, mid, u, v, val);
        update(2 * id + 1, mid + 1, r, u, v, val);
        st[id] = min(st[2 * id], st[2 * id + 1]);
    }
    void set (int id, int l, int r, int pos, int val) {
        if(l > pos || r < pos) return;
        if(l == r) {
            st[id] =  val;
            return;
        }
        int mid = l + r >> 1;
        down(id);
        if(pos <= mid) {
            set(2 * id, l, mid, pos, val);
        }
        else {
            set(2 * id + 1, mid + 1, r, pos, val);
        }
        st[id] = min(st[2 * id], st[2 * id + 1]);

    }
    int get (int id, int l, int r, int u, int v) {
        if(l > v || r < u) return INF;
        if(l >= u && r <= v) {
            return st[id];
        }
        down(id);
        int mid = l + r >> 1;
        return min(get(2 * id, l, mid, u, v), get(2 * id + 1, mid + 1, r, u, v));
    }
};
Seg st[2];
int n, k;
void solve() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        char x; cin >> x;
        if(x == 'W') a[i] = 1;
    }
    for (int i = 1; i <= n; i++) {
        char x; cin >> x;
        if(x == 'W') b[i] = 1;
    }
    st[0] = st[1] = Seg(n);
    for (int i = 1; i <= n; i++) {
        if(i > 1 && b[i] != b[i - 1]) {
            st[b[i - 1]].update(1, 1, n, 1, i - 1, 1);
        }
        st[b[i]].set(1, 1, n, i, dp[i - 1]);
        if(b[i] == a[i]) {
            dp[i] = dp[i - 1];
        }
        else {
            dp[i] = st[b[i]].get(1, 1, n, max(1, i - k + 1), i) + 1;
        }
    } 
    cout << dp[n] << endl;
}

main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int T = 1;
    // cin >> T;
    while (T--) solve();
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 40320
final_rank: 10

code_snippet: // AOJ #1382
// Black or White 2025.2.14

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, k;
    cin >> n >> k;
    string s, t;
    cin >> s >> t;

    s = ' ' + s; // 1-based index に合わせる
    t = ' ' + t;

    vector<vector<int>> pre(2, vector<int>(n + 1));
    for (int i = 1; i <= n; i++) {
        pre[0][i] = pre[0][i - 1];
        pre[1][i] = pre[1][i - 1];
        if (i == 1 || t[i] != t[i - 1]) {
            if (t[i] == 'W') pre[0][i]++;
            else pre[1][i]++;
        }
    }

    deque<int> dqw, dqb;
    dqw.push_back(0);
    dqb.push_back(0);

    vector<int> dp(n + 1, n + 1);
    dp[0] = 0;

    vector<vector<int>> f(2, vector<int>(n + 1));
    f[0][0] = 0;
    f[1][0] = 0;

    for (int i = 1; i <= n; i++) {
        if (s[i] == t[i]) {
            dp[i] = dp[i - 1];
        } else {
            while (!dqw.empty() && dqw.front() < i - k) dqw.pop_front();
            if (!dqw.empty()) dp[i] = min(dp[i], f[0][dqw.front()] + pre[0][i] + 1);

            while (!dqb.empty() && dqb.front() < i - k) dqb.pop_front();
            if (!dqb.empty()) dp[i] = min(dp[i], f[1][dqb.front()] + pre[1][i] + 1);
        }

        int addW = (i < n && t[i] == 'W' && t[i + 1] == 'W') ? 1 : 0;
        int addB = (i < n && t[i] == 'B' && t[i + 1] == 'B') ? 1 : 0;

        f[0][i] = dp[i] - pre[0][i] + addW;
        while (!dqw.empty() && f[0][dqw.back()] > f[0][i]) dqw.pop_back();
        dqw.push_back(i);

        f[1][i] = dp[i] - pre[1][i] + addB;
        while (!dqb.empty() && f[1][dqb.back()] > f[1][i]) dqb.pop_back();
        dqb.push_back(i);
    }
    cout << dp[n] << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 17900
final_rank: 3

code_snippet: // AOJ #1382
// Black or White 2025.2.14

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

char s[500005], t[500005];
void Cins(char *buf) { // 文字列の入力　スペース以下の文字で入力終了
    char *s = buf+1;
	do *s = gc();
	while (*s++ > ' ');
	*(s-1) = 0;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

static inline void chmin(int &a, int b) { if(a > b) a = b; }
 
int main() {
    int n = Cin(), k = Cin();
    Cins(s), Cins(t);

    vector pre(2, vector<int>(n+1));
    for (int i = 1; i <= n; i++){
        pre[0][i] = pre[0][i-1];
        pre[1][i] = pre[1][i-1];
        if(i == 1 || t[i] != t[i-1]){
            if(t[i] == 'W') pre[0][i]++;
            else            pre[1][i]++;
        }
    }
 
    deque<int> dqw, dqb;
    dqw.push_back(0);
    dqb.push_back(0);

    vector dp(n+1, 0);
    dp[0] = 0;
    for (int i = 1; i <= n; i++) dp[i] = n + 1;

    vector f(2, vector<int>(n+1));
    f[0][0] = 0;
    f[1][0] = 0;
 
    for (int i = 1; i <= n; i++){
        if(s[i] == t[i]) dp[i] = dp[i-1];
        else {
            while(!dqw.empty() && dqw.front() < i - k) dqw.pop_front();
            if(!dqw.empty()) chmin(dp[i], f[0][dqw.front()] + pre[0][i] + 1);
 
            while(!dqb.empty() && dqb.front() < i - k) dqb.pop_front();
            if(!dqb.empty()) chmin(dp[i], f[1][dqb.front()] + pre[1][i] + 1);
        }
 
        int addW = (i < n && t[i] == 'W' && t[i+1] == 'W') ? 1 : 0;
        int addB = (i < n && t[i] == 'B' && t[i+1] == 'B') ? 1 : 0;
        f[0][i] = dp[i] - pre[0][i] + addW;
        while(!dqw.empty() && f[0][dqw.back()] > f[0][i]) dqw.pop_back();
        dqw.push_back(i);
 
        f[1][i] = dp[i] - pre[1][i] + addB;
        while(!dqb.empty() && f[1][dqb.back()] > f[1][i]) dqb.pop_back();
        dqb.push_back(i);
    }
    Cout(dp[n]);
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 17828
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for (int i = (a); i <= (int)(b); ++i)
const int maxn = 5e5 + 10, INF = 0x3f3f3f3f;
char s[maxn], t[maxn];
struct Queue {
  struct Node {
    int pos, val;
  }; // node[maxn];
  list<Node> Q;
  // int l, r;
  // void init() { l = 1, r = 0; }
  void init() { Q.clear(); }
  void update(int pos, int val, int k) {
    while (!Q.empty() and val < Q.back().val) Q.pop_back();

    // while (l <= r && val < node[r].val) r--;
    Q.push_back({pos, val});
    // node[++r] = Node{pos, val};
    while (!Q.empty() and pos - Q.front().pos >= k) Q.pop_front();
    // while (l <= r && node[r].pos - node[l].pos >= k) l++;
  }
  int Qry() {
    return Q.empty() ? INF : Q.front().val;
    // if (l > r) return INF;
    // return node[l].val;
  }
} Q;
int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  int n, k;
  cin >> n >> k >> (s + 1) >> (t + 1);
  vector<int> D(n + 1, INF), sum(n + 2);
  sum[0] = 0, t[0] = '#';
  REP(i, 1, n) sum[i] = sum[i - 1] + (t[i] != t[i - 1]);
  D[0] = 0, Q.init(), Q.update(0, 2 * D[0] - sum[1], k);
  REP(i, 1, n) {
    // D[i] = INF;
    D[i] = s[i] == t[i] ? D[i - 1] : (Q.Qry() + sum[i] + 3) / 2;
    // if (s[i] == t[i])
    //   D[i] = D[i - 1];
    // else
    //   D[i] = min(D[i], (Q.Qry() + sum[i] + 3) / 2);
    Q.update(i, 2 * D[i] - sum[i + 1], k);
  }
  printf("%d\n", D[n]);
  return 0;
}

/*
   D[i]:前i个位置染完的最小花费, 初始D[0] = 0, D[i>0] = ∞
   s[i] = t[i]时， D[i] = D[i-1]
   否则 D[i] = min{D[j] + cost(j+1,i)| max(0, i-k)≤j<i}
   其中 cost(x, y): ⌈(sum[i]-sum[j+1])/2⌉+1 = (sum[i]-sum[j+1]+1)/2+1
   于是有： D[i] = minⱼ{(2*D[j]-sum[j+1]+sum[i]+3)/2 | max(0,i-k) <= j < i}
   定义 f[j] = 2*D[j] - sum[j+1]
   于是 D[i]=min{(f[j]+sum[i]+3)/2 | max(0,i-k) <= j < i }
   用长度为k的滑动窗口单调队列来维护即可，之后 f[i] = 2*D[i]-sum[i+1]入队
*/
accuracy: 1
time_ms: 20
memory_kb: 23504
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)
#define ll long long
#define INF (ll)(1ll << 60)
struct SegTree {
    ll sz;
    vector<ll> dat;
    SegTree(ll n) {
        sz = 1;
        while (sz < n) sz *= 2;
        dat.resize(2 * sz - 1, INF);

    }
    void update(ll a, ll x){
        a += sz - 1;
        dat[a] = x;
        while(a > 0){
            a = (a - 1) / 2;
            dat[a] = min(dat[a * 2 + 1], dat[a * 2 + 2]);
        }
    }
    ll query(ll a, ll b, ll k = 0, ll l = 0, ll r = -1){
        if(r < 0)r = sz;
        if(r <= a or b <= l)return INF;
        if(a <= l and r <= b)return dat[k];
        ll q1, q2;
        q1 = query(a, b, k * 2 + 1, l, (l + r) / 2);
        q2 = query(a, b, k * 2 + 2, (l + r) / 2, r);
        return min(q1, q2);
    }
};


SegTree seg(510000), w(510000), b(510000);

vector<ll> ok(510000, -1);
int main(){
    ll n, k;
    cin >> n >> k;
    string s, t;
    cin >> s >> t;

    seg.update(0, 0);
    w.update(0, 0);
    b.update(0, 0);
    REP(i, n){
        if(s[i] == t[i])ok[i] = i;
    }
    REP(i, n){
        if(ok[i] != -1 and ok[i + 1] != -1)ok[i+1]=ok[i];
    }
    ll nb = 0, nw = 0, eb = 0, ew = 0;
    REP(i, n){
        ll now = INF;
        if(i == 0 or t[i - 1] != t[i]){
            if(t[i] == 'B')nb++;
            else nw++;
        }
        if(ok[i] != -1)now = min(now, seg.query(ok[i], i + 1));
         
        if(i == n - 1 or t[i] != t[i + 1]){
            if(t[i] == 'B')eb++;
            else ew++;
        }
        
        //w
        now = min(now, 1 + nb + w.query(max(0ll, i - k + 1), i + 1));
        now = min(now, 1 + nw + b.query(max(0ll, i - k + 1), i + 1));
        seg.update(i + 1, now);
        
        w.update(i + 1, now - eb);
        b.update(i + 1, now - ew);
        //cout << nb << " " << nw << " " << eb <<" " << ew << " "<< seg.query(i, i + 1) << endl;
    }
    cout << seg.query(n, n + 1) << endl;
}
accuracy: 1
time_ms: 270
memory_kb: 32856
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vl=vector<ll>;
#define rep3(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define rep2(i,a,b) rep3(i,a,b,1)
#define rep1(i,n) rep2(i,0,n)
#define rep0(n) rep1(aaaaaaaaaa,n)
#define ov4(a,b,c,d,name,...) name
#define rep(...) ov4(__VA_ARGS__,rep3,rep2,rep1,rep0) (__VA_ARGS__)
#define per(i,a,b) for(ll i=(a)-1;i>=(b);i--)
#define all(a) begin(a),end(a)
#define lb(v,x) (lower_bound(all(v),x)-begin(v)) 
#define fore(e,v) for(auto &&e: v)
#define sz(a) ((int)a.size())
#define eb emplace_back
template<typename T,typename S> bool chmin(T& a,const S& b){
    return a>b?a=b,1:0;
}
struct _{
    _(){
        cin.tie(0)->sync_with_stdio(0),cout.tie(0);
    };
}__;

template<class S,S (*op)(S,S),S (*e)()>struct segtree{
    segtree(int n) : segtree(vector<S>(n,e())){}
    segtree(const vector<S>& v): n(sz(v)){
        s=bit_ceil(unsigned(n));
        log=countr_zero(unsigned(s));
        d=vector<S>(2*s,e());
        rep(i,n)d[s+i]=v[i];
        per(i,s,1)update(i);
    }
    void set(int p,S x){
        d[p+=s]=x;
        rep(i,1,log+1)update(p>>i);
    }
    S prod(int l,int r)const {
        S sml=e(),smr=e();
        l+=s,r+=s;
        while(l<r){
            if(l&1)sml=op(sml,d[l++]);
            if(r&1)smr=op(d[--r],smr);
            l>>=1,r>>=1;
        }
        return op(sml,smr);
    }
    S all_prod()const{
        return d[1];
    }
    S get(int p){
        return d[p+s];
    }
    private:
    int n,s,log;
    vector<S> d;
    void update(int k){
        d[k]=op(d[k*2],d[k*2+1]);
    }
};

ll seg_op(ll a,ll b){
    return min(a,b);
}
ll seg_e(){
    return (ll)1e18;
}

int main(){
    int N,K;
    cin>>N>>K;
    string S,T;
    cin>>S>>T;
    vi cnt(N+1);
    rep(i,N-1){
        cnt[i+1]=cnt[i]+(T[i]!=T[i+1]);
    }
    cnt[N]=cnt[N-1];
    // for(int i:cnt)cerr<<i<<' ';
    // cerr<<endl;
    segtree<ll,seg_op,seg_e> dp(N+1);
    dp.set(0,0);
    rep(i,N){
        if(S[i]==T[i]){
            ll cost=(dp.get(i)+cnt[i]-cnt[i+1]);
            dp.set(i+1,cost);
        }
        // rep(j,N+1)cerr<<dp.get(j)<<' ';
        // cerr<<endl;
        // cerr<<i+1-K<<' '<<dp.prod(max(0,i+1-K),i+1)<<' ';
        ll cost=(dp.prod(max(0,i+1-K),i+1)+cnt[i]+3)/2;
        // cerr<<cost<<' ';
        ll dpv=cost*2-cnt[i+1];
        // cerr<<dpv<<' ';
        if(dp.get(i+1)>dpv){
            dp.set(i+1,dpv);
        }
        // cerr<<dp.get(i)<<endl;
    }
    // cerr<<dp.get(N)<<endl;
    ll ans=(dp.get(N)+cnt[N])/2;
    cout<<ans<<'\n';
}
accuracy: 1
time_ms: 40
memory_kb: 18568
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,a,b) for(ll i = a; i < b; i++)
#define all(a) (a).begin(), (a).end()

int main(){
    ll n,k;
    cin>>n>>k;
    string s;
    cin>>s;
    string t;
    cin>>t;
    vector<ll> dp(n+1,100000000);
    dp[0]=0;
    priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>> pq;
    vector<ll> tiga(n+1);
    rep(i,0,n-1){
        tiga[i+1]=tiga[i];
        if(t[i]!=t[i+1])tiga[i+1]++;
    }
    pq.push(make_pair(0,0));
    rep(i,0,n){
        if(s[i]==t[i])dp[i+1]=dp[i];
        else{
            while(i+1>pq.top().second+k) {
                pq.pop();
            }
            
            dp[i+1]=(pq.top().first+tiga[i]+3)/2;
        }
        pq.push(make_pair(dp[i+1]*2-tiga[i+1],i+1));
    }
    cout<<dp[n]<<endl;
}
accuracy: 1
time_ms: 30
memory_kb: 22544
final_rank: 6

code_snippet: #include<bits/stdc++.h>
#define rep(i,s,n) for (int i = (int)(s); i < (int)(n); i++)
#define all(v) begin(v),end(v)
using namespace std;
using ll = long long;
bool chmin(auto &a, auto b){ return a > b ? a = b, 1 : 0; }
bool chmax(auto &a, auto b){ return a < b ? a = b, 1 : 0; }

template<class S, auto op, auto e> struct segtree {
    int n, sz;
    vector<S> d;
    void upd(int k) { d[k] = op(d[2*k], d[2*k+1]); }
    segtree(int _n=0) : segtree(vector<S>(_n,e())){}
    segtree(vector<S> v) : n(v.size()) {
        sz = bit_ceil<uint32_t>(n);
        d = vector<S>(sz*2, e());
        rep(i,0,n) d[sz+i] = v[i];
        for (int i=sz-1; i>=1; i--) upd(i);
    }
    S prod(int l, int r) {
        S sml= e(), smr = e();
        l+=sz,r+=sz;
        while (l<r) {
            if (l&1)sml=op(sml,d[l++]);
            if (r&1)smr=op(d[--r],smr);
            l>>=1;r>>=1;
        }
        return op(sml, smr);
    }
    void set(int p, S x) {
        p +=sz;
        d[p]=x;
        while (p>>=1) upd(p);
    }
    S get(int p) { return d[p+sz];}
    int max_right(int l, auto f) {
        if (l ==n) return n;
        l+=sz;
        S sm=e();
        do {
            while (l%2==0)l>>=1;
            if (!f(op(sm,d[l]))) {
                while (l<sz) {
                    l<<=1;
                    if (f(op(sm,d[l]))) {sm=op(sm,d[l++]);}

                }
                return l-sz;
            }
            sm=op(sm,d[l++]);
        }while ((l&-l)!=l);
        return n;
    }
    int min_left(int r, auto f) {
        if (r==0) return 0;
        r+=sz;
        S sm=e();
        do {
            r--;
            while (r>1&&(r%2))r>>=1;
            if (!f(op(d[r],sm))) {
                while (r<sz) {
                    r=2*r+1;
                    if (f(op(d[r],sm))) {
                        sm=op(d[r--],sm);
                    }
                }
                return r+1-sz;
            }
            sm=op(d[r],sm);
        }while ((r&-r)!=r);
        return 0;
    }
};

const int iinf = 1e9;

int op(int a, int b) {
    return min(a,b);
}
int e() {
    return iinf;
}

void solve() {
    int n, k; cin >> n >> k;
    string s, t; cin >> s >> t;
    vector<int> q(n);
    rep(i,0,n-1) {
        q[i+1] = q[i] + int(t[i] != t[i+1]);
    }
    array<segtree<int,op,e>,2> segs;
    rep(i,0,2) segs[i] = segtree<int,op,e>(n+1);
    segtree<int,op,e> dp(n+1);
    dp.set(0,0);
    segs[q[0]&1].set(0,dp.get(0)*2 - q[0]);
    segtree<int,op,e> same(n);
    rep(i,0,n) {
        if (s[i] != t[i]) {
            same.set(i,0);
        }
    }
    rep(i,1,n+1) {
        // same
        int val = e();
        {
            auto f = [&](int x) {
                return x == e();
            };
            int l = same.min_left(i,f);
            chmin(val, dp.prod(l,i));
        }
        // neq 0
        {
            int cur = segs[q[i-1]&1].prod(i-k,i) + q[i-1] + 2;
            assert(cur % 2 == 0 || cur >= iinf);
            cur /= 2;
            chmin(val, cur);
        }
        // neq 1
        {
            int cur = segs[~q[i-1]&1].prod(i-k,i) + q[i-1]+1 + 2;
            assert(cur % 2 == 0 || cur >= iinf);
            cur /= 2;
            chmin(val, cur);
        }
        dp.set(i,val);
        if (i == n) break;
        segs[q[i]&1].set(i,val*2 - q[i]);
    }
    cout << dp.get(n) << endl;
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    solve();
}
accuracy: 1
time_ms: 110
memory_kb: 24680
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    int N, K;
    cin >> N >> K;
    vector<int> S(N), T(N);
    rep(i,0,N) {
        char c;
        cin >> c;
        if (c == 'B') S[i] = 1;
        else S[i] = 0;
    }
    rep(i,0,N) {
        char c;
        cin >> c;
        if (c == 'B') T[i] = 1;
        else T[i] = 0;
    }
    vector<vector<int>> C(N+1, vector<int>(2,0));
    rep(i,0,N) {
        C[i+1][T[i]] = C[i][T[i]];
        if (i != N-1 && T[i] != T[i+1]) {
            C[i+1][T[i]^1] = C[i][T[i]^1] + 1;
        }
        else {
            C[i+1][T[i]^1] = C[i][T[i]^1];
        }
    }
    vector<int> ANS(N+1, inf);
    ANS[0] = 0;
    vector<deque<pair<int,int>>> SWAG(2);
    rep(i,0,2) SWAG[i].push_back({0,0});
    rep(i,1,N+1) {
        rep(j,0,2) while(SWAG[j].front().second < i-K) SWAG[j].pop_front();
        if (S[i-1] != T[i-1]) ANS[i] = SWAG[T[i-1]].front().first + C[i][T[i-1]] + 1;
        else ANS[i] = ANS[i-1];
        rep(j,0,2) {
            pair<int,int> NEXT = {ANS[i]-C[i][j], i};
            while(!SWAG[j].empty() && SWAG[j].back().first > NEXT.first) SWAG[j].pop_back();
            SWAG[j].push_back(NEXT);
        }
    }
    cout << ANS[N] << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 44580
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
#define ALL(v) v.begin(),v.end()
#define dbg(x) cerr << #x << ": " << (x) << endl;

template<class S, S(*op)(S,S), S(*e)()>
struct SegTree {
    int n, size;
    vector<S> d;
    SegTree(int n) : n(n) {
        size = 1;
        while (size < n) size  <<= 1;
        d.resize(2 * size, e());
    }
    void set(int idx, S val) {
        idx += size;
        d[idx] = val;
        while (idx > 0) {
            idx >>= 1;
            d[idx] = op(d[idx*2], d[idx*2+1]);
        }
    }
    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= n);
        l += size;
        r += size;
        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(d[l++], sml);
            if (r & 1) smr = op(smr, d[--r]);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }
};
ll op(ll a, ll b) {
    return min(a,b);
}
ll e() {
    return 1e18;
}

int main() {
    int n, k;
    cin >> n >> k;
    string s, t;
    cin >> s >> t;
    s.push_back('B');
    t.push_back('B');

    vector<int> sum(n + 2);
    for (int i = 0; i < n; ++i) sum[i + 1] = sum[i] + (t[i + 1] != t[i]);
    
    SegTree<ll, op, e> sgb(n + 5), sgw(n + 5);
    vector<ll> dpb(n + 5), dpw(n + 5);
    if (t[0] == 'B') sgb.set(0, 0);
    else sgw.set(0, 0);

    long long ans;
    for (int i = 1; i <= n; ++i)
    {
        ll ret = min(sgb.prod(i - 1, i), sgw.prod(i - 1, i)) + sum[i - 1] + 2 * (s[i - 1] != t[i - 1]);
        if (t[i - 1] == 'B')
        {
            ret = min(ret, sgb.prod(max(i - k, 0), i) + 2 + sum[i - 1]);
        }
        else
        {
            ret = min(ret, sgw.prod(max(i - k, 0), i) + 2 + sum[i - 1]);
        }
        if (t[i] == 'B') sgb.set(i, ret - sum[i]);
        else sgw.set(i, ret - sum[i]);
        if (i == n)
        {
            ans = ret / 2;
            break;
        }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 30472
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
int main(){
    int N,K;
    string S,T;
    cin>>N>>K>>S>>T;
    vector<int> DP(N+1,0),WB(N+1,0),BW(N+1,0);
    multiset<int> WBS,BWS;
    WBS.insert(0);
    BWS.insert(0);
    for(int i=0;i<N;i++){
        if(i>=K){
            WBS.erase(WBS.find(DP[i-K]-WB[i-K]));
            BWS.erase(BWS.find(DP[i-K]-BW[i-K]));
        }
        WB[i+1]=WB[i];
        BW[i+1]=BW[i];
        if(i!=N-1){
            BW[i+1]+=(T.substr(i,2)=="BW");
            WB[i+1]+=(T.substr(i,2)=="WB");
        }
        int m=1+(*((S[i]=='B'?BWS:WBS).begin()));
        if(S[i]==T[i])DP[i+1]=DP[i];
        else if(S[i]=='B')DP[i+1]=m+BW[i+1];
        else DP[i+1]=m+WB[i+1];
        BWS.insert(DP[i+1]-BW[i+1]);
        WBS.insert(DP[i+1]-WB[i+1]);
    }
    cout<<DP[N]<<endl;
}
accuracy: 1
time_ms: 270
memory_kb: 56856
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;

int main(){

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll N,K;
    string S,T;
    cin>>N>>K>>S>>T;
    vector<ll> DP(N+1,0),WB(N+1,0),BW(N+1,0);
    multiset<ll> WBS,BWS;
    WBS.insert(0);
    BWS.insert(0);
    for(int i=0;i<N;i++){
        if(i-K>=0){
            WBS.erase(WBS.find(DP[i-K]-WB[i-K]));
            BWS.erase(BWS.find(DP[i-K]-BW[i-K]));
        }
        WB[i+1]=WB[i];
        BW[i+1]=BW[i];
        if(i!=N-1){
            if(T.substr(i,2)=="BW")BW[i+1]++;
            if(T.substr(i,2)=="WB")WB[i+1]++;
        }
        ll m=*((S[i]=='B'?BWS:WBS).begin());
        if(S[i]==T[i])DP[i+1]=DP[i];
        else if(S[i]=='B')DP[i+1]=m+BW[i+1]+1;
        else DP[i+1]=m+WB[i+1]+1;
        BWS.insert(DP[i+1]-BW[i+1]);
        WBS.insert(DP[i+1]-WB[i+1]);
    }
    cout<<DP[N]<<endl;
}
accuracy: 1
time_ms: 250
memory_kb: 62732
final_rank: 17

code_snippet: //#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma,popcnt")
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
const int inf = 1e9;
const int N = 5e5 + 7; 

/**
 * Author: NXT
 * Date: 2016-10-08
 * License: CC0
 * Source: NXT
 * Description: Segment tree with ability to set values of large intervals [L, R), and compute max of intervals.
 * Can be changed to other things. 
 * Time: O(\log N).
 * Status: tested
 */

struct STLazy {
	int n;
	vector<int> tr, lz;
	STLazy(int n) : n(n), tr(4*n + 8), lz(4*n + 8) {}

	void push(int v, int lo, int hi) {
		if (lz[v] != 0) {
			tr[v] += lz[v];
			if(lo+1 != hi) {
				lz[v*2] += lz[v];
				lz[v*2+1] += lz[v]; 
			}
			lz[v] = 0;
		}
	}
    void add(int v, int lo, int hi, int l, int r, int val) {
		push(v, lo, hi);
		if (lo >= hi || lo >= r || hi <= l) return;
		if (lo >= l && hi <= r) {
			lz[v] += val; // put lazy tag here
			push(v, lo, hi);
			return;
		}
		int mid = (lo + hi) / 2;
		add(v*2, lo, mid, l, r, val);
		add(v*2 + 1, mid, hi, l, r, val);

		tr[v] = max(tr[2*v], tr[2*v+1]);
    }
	void update(int v, int lo, int hi, int l, int r, int val) {
		push(v, lo, hi);
		if (lo >= hi || lo >= r || hi <= l) return;
		if (lo >= l && hi <= r) {
			lz[v] += val; // put lazy tag here
			push(v, lo, hi);
			return;
		}
		int mid = (lo + hi) / 2;
		update(v*2, lo, mid, l, r, val);
		update(v*2 + 1, mid, hi, l, r, val);

		tr[v] = min(tr[2*v], tr[2*v+1]);
	}
	int query(int v, int lo, int hi, int l, int r) {
		push(v, lo, hi);
		if (lo >= hi || lo >= r || hi <= l) return inf;
		if (lo >= l && hi <= r) return tr[v];

		int mid = (lo + hi)/2;
		int p1 = query(v*2, lo, mid, l, r);
		int p2 = query(v*2 + 1, mid, hi, l, r);
		
		return min(p1, p2);
	}

	void update(int l, int r, int val) {
		update(1, 0, n, l, r, val);
	}
	int query(int l, int r) {
		return query(1, 0, n, l, r);
	}
};


void solve() {
    int n , k; cin >> n >> k;
    string s; cin >> s; 
    string t; cin >> t;        
    if (t[n - 1] == 'B') t[n] = 'W';
    else t[n] = 'B';
    STLazy ST_W(n);
    STLazy ST_B(n);
    vector<int> f(n + 1);
    int j = 0;
    for (int i = 0 ; i < n ;i ++) {
        //cerr << i << " " << j << '\n';
        if (i == j) {
            while (t[j] == t[j + 1] && j <= n) j++; 
            if (t[i] == 'W') {
                ST_W.add(1 , 0 , n , 0 , j + 1 , 1);
            }
            if (t[j] == 'B') {
                ST_B.add(1 , 0 , n , 0 , j + 1 , 1);
                //cout << i << " " << j << '\n';
            }
            j++;
        }
        ST_W.update(i , i + 1  , f[max(0ll ,i - 1)]);
        ST_B.update(i , i + 1 , f[max(0ll , i - 1)]);
        if (s[i] == t[i]) f[i] = f[max(0ll , i - 1)];
        else {
            int m1 = ST_W.query(max(0ll , i - k + 1) , i + 1);
            int m2 = ST_B.query(max(0ll , i - k + 1) , i + 1);
            //cerr << i << " " << m1 << " " << m2 << '\n';
            f[i] = min(m1 , m2) + 1; 
        }
    }
    // for (int i = 0 ; i < n ; i++) {
    //     cout << f[i] << " ";
    // }
    cout << f[n - 1] << '\n';
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin.exceptions(cin.failbit);
    int test; 
    test = 1;
    //cin >> test;
    while (test--) {
        solve();
    }

}
accuracy: 1
time_ms: 320
memory_kb: 70656
final_rank: 20

code_snippet: //#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma,popcnt")
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef int ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
template <typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
const int inf = 1e18;
const int N = 5e5 + 7; 

struct ST {
  #define lc (n << 1)
  #define rc ((n << 1) | 1)
  int t[4 * N], lazy[4 * N];
  ST() {
    memset(t, 0, sizeof t);
    memset(lazy, 0, sizeof lazy);
  }
  void push(int n, int b, int e) {
    if (lazy[n] == 0) return;
    t[n] = t[n] + lazy[n];
    if (b != e) {
      lazy[lc] = lazy[lc] + lazy[n];
      lazy[rc] = lazy[rc] + lazy[n];
    }
    lazy[n] = 0;
  }
  int combine(int a,int b) {
    return min(a , b);
  }
  void pull(int n , bool stat) {
    if (!stat) t[n] = min(t[lc] , t[rc]);
    else t[n] = max(t[lc] , t[rc]);
    // t[n] = t[lc] + t[rc];
  }
  void upd(int n, int b, int e, int i, int j, int v , bool stat) {
    push(n, b, e);
    if (j < b || e < i) return;
    if (i <= b && e <= j) {
      lazy[n] += v; //set lazy
      push(n, b, e);
      return;
    }
    int mid = (b + e) >> 1;
    upd(lc, b, mid, i, j, v , stat);
    upd(rc, mid + 1, e, i, j, v , stat);
    pull(n , stat);
  }
  int query(int n, int b, int e, int i, int j) {
    push(n, b, e);
    if (i > e || b > j) return inf; //return null
    if (i <= b && e <= j) return t[n];
    int mid = (b + e) >> 1;
    return combine(query(lc, b, mid, i, j), query(rc, mid + 1, e, i, j));
  }
}ST_W , ST_B;


void solve() {
    int n , k; cin >> n >> k;
    vector<int> s(n + 2) , t(n + 2);
    for (int i = 1 ; i <= n ; i++) {
        char x; cin >> x;
        s[i] = (x == 'B');
    }
    for (int i = 1 ; i <= n ; i++) {
        char x; cin >> x;
        t[i] = (x == 'B');
    }  
    t[n + 1] = !t[n];
    vector<int> f(n + 1);
    int j = 1;
    for (int i = 1 ; i <= n ;i ++) {
        //cerr << i << " " << j << '\n';
        if (i == j) {
            while (t[j] == t[j + 1] && j <= n) j++; 
            if (t[i] == 0) {
                ST_W.upd(1 , 1 , n , 1 , j , 1 , 1);
            }
            if (t[i] == 1) {
                ST_B.upd(1 , 1 , n , 1 , j , 1 , 1);
                //cout << i << " " << j << '\n';
            }

            // cerr << i << " " << j << '\n';
            j++;
        }
        ST_W.upd(1 , 1 , n , i , i  , f[i - 1] , 0);
        ST_B.upd(1 , 1 , n , i , i , f[i - 1] , 0);
        if (s[i] == t[i]) f[i] = f[i - 1];
        else {
            int m1 = ST_W.query(1 , 1 , n ,  max(1ll , i - k + 1) , i);
            int m2 = ST_B.query(1 , 1 , n , max(1ll , i - k + 1) , i);
            //cerr << i << " " << m1 << " " << m2 << '\n';
            f[i] = min(m1 , m2) + 1; 
        }
    }
    // for (int i = 0 ; i < n ; i++) {
    //     cout << f[i] << " ";
    // }
    cout << f[n] << endl;
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(0);
    cin.exceptions(cin.failbit);
    int test; 
    test = 1;
    //cin >> test;
    while (test--) {
        solve();
    }

}
accuracy: 1
time_ms: 280
memory_kb: 77288
final_rank: 19

code_snippet: //se+cm
#pragma GCC optimize ("O2")
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define fo(i,a,b) for(ll i=a;i<=b;++i)
#define ff(i,a,b) for(ll i=a;i>=b;--i)
#define fi first
#define se second
#define endl '\n'
#define task "task"
#define task "task"
#define prll pair<ll,ll>
#define pb push_back
#define ld long double
const ll MIN=-1e18,MAX=1e18,MOD=1e9+7,N=5e5+5;
struct segtree{
	ll tree[4*N],lazy[4*N];
	void pushdown(ll node){
		tree[node*2]+=lazy[node];
		tree[node*2+1]+=lazy[node];
		lazy[node*2]+=lazy[node];
		lazy[node*2+1]+=lazy[node];
		lazy[node]=0;
	}
	void add(ll node,ll l,ll r,ll u,ll v){
		if(l>v or r<u) return;
		if(l>=u and r<=v){
			tree[node]+=1;
			lazy[node]+=1;
			return;
		}
		pushdown(node);
		ll m=(l+r)/2;
		add(node*2,l,m,u,v);
		add(node*2+1,m+1,r,u,v);
		tree[node]=max(tree[node*2],tree[node*2+1]);
 	}
 	void update(ll node,ll l,ll r,ll u,ll v){
 		if(l>u or r<u) return;
 		if(l==r){
 			tree[node]+=v;
 			return;
 		}
 		pushdown(node);
 		ll m=(l+r)/2;
 		update(node*2,l,m,u,v);
 		update(node*2+1,m+1,r,u,v);
 		tree[node]=min(tree[node*2],tree[node*2+1]);
 	}
 	ll get(ll node,ll l,ll r,ll u,ll v){
 		if(l>v or r<u) return MAX;
 		if(l>=u and r<=v) return tree[node];
 		pushdown(node);
 		ll m=(l+r)/2;
 		return min(get(node*2,l,m,u,v),get(node*2+1,m+1,r,u,v));
 	}
} tree[2];
ll f[N],b[N],c[N];
int main(){
	// #ifndef ONLINE_JUDGE
	// 	freopen(task".inp","r",stdin);
	// 	freopen(task".out","w",stdout);
	// #endif
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	ll a,k;
	cin>>a>>k;
	char x;
	fo(i,1,a){
		cin>>x;
		b[i]=(x=='B');
	}	
	fo(i,1,a){
		cin>>x;
		c[i]=(x=='B');
	}
	// fo(i,1,a) cout<<b[i]<<" "<<c[i]<<endl;
	c[a+1]=!c[a];
	ll j=1;
	fo(i,1,a){
		if(i==j){
			while(c[j+1]==c[j] and j<=a) j++;
			tree[c[i]].add(1,1,a,1,j);
			// cout<<i<<" "<<j<<endl;
			j++;
		}
		// cout<<tree[0].get(1,1,a,i,i)<<" "<<tree[1].get(1,1,a,i,i)<<endl;
		tree[0].update(1,1,a,i,f[i-1]);
		tree[1].update(1,1,a,i,f[i-1]);
		// cout<<tree[0].get(1,1,a,i,i)<<" "<<tree[1].get(1,1,a,i,i)<<endl;
		// cout<<endl;
		if(b[i]==c[i]) f[i]=f[i-1];
		else{
			ll temp1=tree[0].get(1,1,a,max((ll)1,i-k+1),i);
			ll temp2=tree[1].get(1,1,a,max((ll)1,i-k+1),i);
			f[i]=min(temp1,temp2)+1;
		}
	}
	cout<<f[a]<<endl;
}
/*

*/
accuracy: 1
time_ms: 260
memory_kb: 54648
final_rank: 15

code_snippet: #include <bits/stdc++.h>

#define rep(i,s,n) for(int i = int(s); i < int(n); i++)
#define rrep(i,s,n) for(int i = int(n) - 1; i >= int(s); i--)
#define all(v) (v).begin(), (v).end()

using ll = long long;
using ull = unsigned long long;
using ld = long double;

template<class T>
bool chmin(T &a, T b) {
    if(a <= b) return false;
    a = b;
    return true;
}

template<class T>
bool chmax(T &a, T b) {
    if(a >= b) return false;
    a = b;
    return true;
}

using namespace std;
const int iinf = 1e9;


template <class S, S (*op)(S, S), S(*e)(), class F, S(*mapping)(F, S), F (*composition)(F, F), F(*id)()>
struct lazysegtree {
    private:
        int n, lg2, sz;
        vector<S> d;
        vector<F> lz;
        void update(int i){
            d[i] = op(d[2*i], d[2*i+1]);
        }
        void all_apply(int i, F f){
            d[i] = mapping(f, d[i]);
            if (i < sz) lz[i] = composition(f, lz[i]);
        }

        void push(int i){
            all_apply(2*i, lz[i]);
            all_apply(2*i+1, lz[i]);
            lz[i] = id();
        }

    public:
        lazysegtree(int _n) : lazysegtree(vector<S>(_n, e())) {}
        lazysegtree(const vector<S> &v): n(v.size()){
            lg2 = 0l;
            while((1<<lg2) < n) lg2++;
            sz = 1 << lg2;
            d = vector<S>(2*sz, e());
            lz = vector<F>(2*sz, id());
            rep(i,0,n) d[sz+i] = v[i];
            rrep(i,1,sz) update(i);
        }
        void set(int p, S x){
            assert(0<=p&&p<n);
            p+=sz;
            rrep(i,1,lg2+1) push(p>>i);
            d[p] = x;
            rep(i,1,lg2+1) update(p>>i);
        }

        S get(int p){
            assert(0<=p&&p<n);
            p+=sz;
            rrep(i,1,lg2+1)push(p>>i);
            return d[p];
        }
        S prod(int l, int r){
            assert(0<=l&&l<=r&&r<=n);
            if (l==r)return e();
            l+=sz;
            r+=sz;
            rrep(i,1,lg2+1){
                if (((l>>i)<<i)!=l)push(l>>i);
                if (((r>>i)<<i)!=r)push((r-1)>>i);
            }

            S sml = e(), smr = e();
            while(l<r){
                if (l&1) sml=op(sml,d[l++]);
                if (r&1) smr=op(d[--r],smr);
                l>>=1;
                r>>=1;
            }
            return op(sml, smr);
        }
        S all_prod(){return d[1];}
        void apply(int p, F f){
            assert(0<=p&&p<n);
            p+=sz;
            rrep(i,1,lg2+1)push(p>>i);
            d[p]=mapping(f,d[p]);
            rep(i,1,lg2+1)update(p>>i);
        }
        void apply(int l, int r, F f){
            assert(0<=l&&l<=r&&r<=n);
            if(l==r)return;
            l+=sz;
            r+=sz;
            rrep(i,1,lg2+1){
                if(((l>>i)<<i)!=l) push(l>>i);
                if(((r>>i)<<i)!=r) push((r-1)>>i);
            }
            {
                int l2 = l, r2 = r;
                while(l < r){
                    if (l&1) all_apply(l++,f);
                    if(r&1) all_apply(--r,f);
                    l>>=1;
                    r>>=1;
                }
                l=l2;
                r=r2;
            }
            rep(i,1,lg2+1){
                if(((l>>i)<<i)!=l) update(l>>i);
                if(((r>>i)<<i)!=r) update((r-1)>>i);
            }
        }
};

using pii = pair<int,int>;

pii op(pii a, pii b){
    return pii(min(a.first,b.first),min(a.second,b.second));
}
pii e(){
    return pii(iinf,iinf);
}
pii mapping(int f, pii x){
    if (f % 2 == 1){
        x.second += 1;
        swap(x.first,x.second);
        f--;
    }
    x.first += f/2;
    x.second += f/2;
    return x;
}
int composition(int f, int g){
    return f + g;
}
int ideal(){
    return 0;
}

int main() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int n, k; cin >> n >> k;
    string s, t; cin >> s >> t;
    lazysegtree<pii,op,e,int,mapping,composition,ideal> seg(n+1);
    seg.set(0,pii(0,iinf));
    int predp = 0;
    rep(i,0,n){
        int dp = (s[i] == t[i] ? predp : iinf);
        if (i > 0 && t[i-1] != t[i]){
            seg.apply(0,i,1);
        }
        seg.apply(i,1);
        auto val = seg.prod(max(i+1-k,0),i+1);
        chmin(dp,min(val.first,val.second)+1);
        seg.set(i+1,pii(dp,iinf));
        predp = dp;
    }
    cout << predp << endl;
}
accuracy: 1
time_ms: 260
memory_kb: 20472
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define rep(i, n) for(int i = 1; i <= n; ++i)
#define forn(i, l, r) for(int i = l; i <= r; ++i)
#define ford(i, r, l) for(int i = r; i >= l; --i)
#define FOR(i, n) for(int i = 0; i < n; ++i)
#define fi first
#define se second
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define task "MEETING"
#define endl "\n"
#define sz(a) int(a.size())
#define C(x, y) make_pair(x, y)
#define all(a) (a).begin(), (a).end()
#define bit(i, mask) (mask >> i & 1)

template<typename T> bool maximize(T &res, const T &val) { if (res <= val){ res = val; return true; }; return false; }
template<typename T> bool minimize(T &res, const T &val) { if (res >= val){ res = val; return true; }; return false; }


const int N =  5e5 + 10;
const int K = 1e2 + 1;
const int MOD = 1e9 + 7;
const int INF = 1e9 + 1;
const int block_size = 230;
const int LOG = 17;
const int offset = N;
const int LIM = 2e5;
const int AL = 26;
const int M = 11;
const int lim = (1 << 10) - 1;

int n, k;

string s;
string t;

int dp[N];

struct SegmentTree
{
    int st[N << 2], lz[N << 2];

    void push(int id, int l, int r)
    {
        int mid = l + r >> 1;
        lz[id << 1] += lz[id];
        lz[id << 1 | 1] += lz[id];
        st[id << 1] += lz[id];
        st[id << 1 | 1] += lz[id];
        lz[id] = 0;
    }

    void update(int id, int l, int r, int u, int v, int val)
    {
        if(r < u || l > v) return;
        if(u <= l && r <= v)
        {
            lz[id] += val;
            st[id] += val;
            return;
        }
        push(id, l, r);
        int mid = l + r >> 1;
        update(id << 1, l, mid, u, v, val);
        update(id << 1 | 1, mid + 1, r, u, v, val);
        st[id] = min(st[id << 1], st[id << 1 | 1]);
    }

    int get(int id, int l, int r, int u, int v)
    {
        if(r < u || l > v) return INF;
        if(u <= l && r <= v) return st[id];
        
        push(id, l, r);
        int mid = l + r >> 1;
        return min(get(id << 1, l, mid, u, v), 
                    get(id << 1 | 1, mid + 1, r, u, v));
    }
} St_w, St_b;

void solve()
{
    cin >> n >> k;
    cin >> s;
    cin >> t;
    dp[0] = 0;
    rep(i, n)
    {
        dp[i] = dp[i - 1] + (s[i - 1] != t[i - 1]);
        St_b.update(1, 1, n, i, i, dp[i - 1]);
        St_w.update(1, 1, n, i, i, dp[i - 1]);
        if(t[i - 1] == 'B') St_b.update(1, 1, n, i, i, 1);
        else St_w.update(1, 1, n, i, i, 1);
        if(i != 1 && t[i - 1] != t[i - 2])
            if(t[i - 1] == 'B') St_b.update(1, 1, n, max(1, i - k + 1), i - 1, 1);
        else St_w.update(1, 1, n, max(1, i - k + 1), i - 1, 1);
        minimize(dp[i], St_b.get(1, 1, n, max(1, i - k + 1), i) + 1);
        minimize(dp[i], St_w.get(1, 1, n, max(1, i - k + 1), i) + 1);
        //cout << t[i - 1] << endl;
        //rep(j, i) cout << St_w.get(1, 1, n, j, j) << " "; cout << endl;
    }
    cout << dp[n];

}

signed main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    if(fopen("XQUERY.inp", "r"))
    {
        freopen("XQUERY.inp", "r", stdin);
        freopen("XQUERY.out", "w", stdout);
    }

    int TC = 1;

    while(TC--)
    {
        solve();
        cout << endl;
    }

    return 0;
}
//ha
accuracy: 1
time_ms: 390
memory_kb: 31280
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
using ll = long long;
template<class T> bool chmin(T &a,const T b){if(a>b){a=b;return 1;}return 0;}
template<class T> bool chmax(T &a,const T b){if(a<b){a=b;return 1;}return 0;}
const int INF = (1<<30)-1;
const int mod=998244353;
#define all(p) p.begin(),p.end()

int main(){
	int N,K;
	cin>>N>>K;
	string S,T;
	cin>>S>>T;
	map<int,int> m;
	vector<int> dp(N+1);
	vector<int> diff(N+1);
	rep(i,0,N){
		if(S[i]==T[i]) dp[i+1]=dp[i];
		else dp[i+1]=dp[i]+1;
		diff[i+1]=diff[i];
		if(i!=0&&T[i]!=T[i-1]) diff[i+1]++;
		m[dp[i]*2-diff[i+1]]++;
		chmin(dp[i+1],((*m.begin()).first+diff[i+1]+1)/2+1);
		if(0<=i+1-K){
			int val=dp[i+1-K]*2-diff[i+2-K];
			m[val]--;
			if(m[val]==0) m.erase(val);
		}
		/*
		cout<<i+1<<endl;
		cout<<dp[i+1]<<endl;
		for(auto x:m) cout<<x.first<<" "<<x.second<<endl;
		*/
	}
	cout<<dp[N]<<"\n";
}
accuracy: 1
time_ms: 30
memory_kb: 8804
final_rank: 1

code_snippet: #pragma GCC optimize ("O2")
#include <bits/stdc++.h>

#define ll long long
#define ld long double
#define fi first 
#define se second
#define pll pair < ll, ll >
#define pii pair < int, int >
#define fast ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);

using namespace std;

const string NAME = "";
const string NAME2 = "TEST";
const ld ESP = 1e-9;
const ll INF = 1e9 + 7;
const ll LINF = 1E18;
const ll nmax = 2e5;
const ll MOD = 1e9 + 7;
const ll base = 2309;

void fre() {
	string finp = NAME + ".inp";
	string fout = NAME + ".out";	
	freopen(finp.c_str(), "r", stdin);
	freopen(fout.c_str(), "w", stdout);
}

ll n, k, a[500003], b[500003], dp[500003], it[2][4000003], lazy[2][4000003];

void update_node(int id, int node, int l, int r) {
	if (lazy[id][node] != 0) {
		it[id][node] += lazy[id][node];
		if (l != r) {
			lazy[id][node * 2] += lazy[id][node];
			lazy[id][node * 2 + 1] += lazy[id][node];
		}
		lazy[id][node] = 0;
	}
}

void update(int node, int l, int r, int u, int v, int id, int val) {
	update_node(id, node, l, r);
	if (v < l || r < u) return ;
	if (u <= l && r <= v) {
		lazy[id][node] = val;
		update_node(id, node, l, r);
		return ;
	}
	int mid = (l + r) / 2;
	update(node * 2, l, mid, u, v, id, val);
	update(node * 2 + 1, mid + 1, r, u, v, id, val);
	it[id][node] = min(it[id][node * 2], it[id][node * 2 + 1]);
}

int query(int node, int l, int r, int u, int v, int id) {
	update_node(id, node, l, r);
	if (v < l || r < u) return INF;
	if (u <= l && r <= v) return it[id][node];
	int mid = (l + r) / 2;
	return min(query(node * 2, l, mid, u, v, id), query(node * 2 + 1, mid + 1, r, u, v, id));
}

int main() {
	fast;
	cin >> n >> k;
	a[0] = b[0] = -1;
	for (int i = 1; i <= n; i++) {
		char c;
		cin >> c;
		if (c == 'B') a[i] = 1;
	}
	for (int i = 1; i <= n; i++) {
		char c;
		cin >> c;
		if (c == 'B') b[i] = 1;
	}
	for (int i = 1; i <= n; i++) {
		if (b[i] != b[i - 1]) {
			int j = i;
			while (j < n && b[j + 1] == b[i]) j ++;
			update(1, 0, n, 0, j - 1, b[i], 1);
			//if (b[i] == 0) cout << 0 << " " << j - 1 << " " << 1 << '\n';
		}
		if (b[i] != a[i]) {
			int j = max(0ll, i - k);
			//if (i == 4) cout << query(1, 0, n, j, i - 1, 0) << '\n';
			dp[i] = min(query(1, 0, n, j, i - 1, 0), query(1, 0, n, j, i - 1, 1)) + 1;
		}
		else dp[i] = dp[i - 1];
		//cout <<i << " " << i << " " << dp[i] << '\n';
		update(1, 0, n, i, i, 0, dp[i]);
		update(1, 0, n, i, i, 1, dp[i]);
	}
	cout << dp[n] << '\n';
}
accuracy: 1
time_ms: 410
memory_kb: 47720
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int N = 5e5 + 5, oo = 1e9;

struct stree {
	int n;
	vector<int> st;
	stree() {}
	stree(int n) : n(n) {
		st.resize(4 * (n + 1) + 4, 0);
	}
	void upd(int id, int l, int r, int x, int v) {
		if (l > x || r < x) return;
		if (l == r) {
			st[id] += v; return;
		}
		int mi = (l + r) / 2;
		upd(2 * id, l, mi, x, v); upd(2 * id + 1, mi + 1, r, x, v);
		st[id] = min(st[2 * id], st[2 * id + 1]);
	}
	int get(int id, int l, int r, int u, int v) {
		if (l > v || r < u) return oo;
		if (u <= l && r <= v) return st[id];
		int mi = (l + r) / 2;
		return min(get(2 * id, l, mi, u, v), get(2 * id + 1, mi + 1, r, u, v));
	}
};

int n, k, pre[N];
int dp[N], kep_b[N], del_b[N], kep_w[N], del_w[N];
string a, b;

int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin >> n >> k >> a >> b; a = ' ' + a; b = ' ' + b;
	for (int i = 1; i <= n; ++i) 
		if (b[i] == 'B') {
			++kep_b[i];
			while (i + 1 <= n && b[i + 1] == 'B')
				++i;
			++del_b[i]; 
		}
	for (int i = 1; i <= n; ++i) 
		if (b[i] == 'W') {
			++kep_w[i];
			while (i + 1 <= n && b[i + 1] == 'W')
				++i;
			++del_w[i]; 
		}	
	for (int i = 1; i <= n; ++i) {
		kep_b[i] += kep_b[i - 1];
		del_b[i] += del_b[i - 1];
		kep_w[i] += kep_w[i - 1];
		del_w[i] += del_w[i - 1];
		// cout << kep_b[i] << ' ' << del_b[i] << ' ' << kep_w[i] << ' ' << del_w[i] << '\n';
	}
	for (int i = 1; i <= n; ++i)
		if (a[i] != b[i]) pre[i] = i;
		else if (b[i] == b[i - 1]) pre[i] = pre[i - 1];
		else pre[i] = i - 1;
	// for (int i = 1; i <= n; ++i) cerr << i << ' ' << pre[i] << '\n';
	stree sb(n), sw(n);
	for (int i = 1; i <= n; ++i) {
		dp[i] = oo; dp[i] = dp[pre[i]];
		dp[i] = min(dp[i], sb.get(1, 0, n, max(0, i - k), i - 1) + kep_b[i] + 1);
		dp[i] = min(dp[i], sw.get(1, 0, n, max(0, i - k), i - 1) + kep_w[i] + 1);
		sb.upd(1, 0, n, i, dp[i] - del_b[i]);
		sw.upd(1, 0, n, i, dp[i] - del_w[i]);
		// cerr << i << ' ' << dp[i] << '\n';
	}
	cout << dp[n] << '\n';
	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 31552
final_rank: 11