rt ,本地 (windows) 跑毫无问题, cf 上跑同样的数据就 RE 了,经过反复提交 RE 原因锁定在 39-40 行 (???
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define Mod (1000000007)
using namespace std;
const int MAXN = 500005;
int n, K, L, ans;
char s[MAXN], t[2][MAXN];
int sa[MAXN], pre[MAXN];
int better, G[MAXN << 1][2];
class Suffix_automaton {
private :
struct Node {
int len, edp, endp;
int fail, sons[28];
}tr[MAXN << 1]; int idx, lst;
int ct, indgr[MAXN << 1];
inline int NewNode(int ln) {
tr[++ idx].len = ln;
tr[idx].fail = 0;
memset(tr[idx].sons, 0, sizeof(tr[idx].sons));
return idx;
}
public :
inline void Init() {
ct = 0, lst = NewNode(0);
}
inline void Insert(int x, int pos) {
int p = lst, cur = NewNode(tr[p].len + 1);
tr[cur].edp = tr[cur].endp = pos;
while (p && !tr[p].sons[x])
tr[p].sons[x] = cur, p = tr[p].fail;
if (!p) tr[cur].fail = 1;
else {
int q = tr[p].sons[x];
if (tr[q].len == tr[p].len + 1)
tr[cur].fail = q;
else {
int nq = NewNode(tr[p].len + 1);
tr[nq].fail = tr[q].fail;
memcpy(tr[nq].sons, tr[q].sons, sizeof(tr[q].sons));
tr[q].fail = tr[cur].fail = nq;
while (p && tr[p].sons[x] == q)
tr[p].sons[x] = nq, p = tr[p].fail;
}
}
lst = cur;
}
inline void Build() {
for (int i = 2; i <= idx; ++ i)
++ indgr[tr[i].fail];
queue<int>q;
for (int i = 1; i <= idx; ++ i)
if (!indgr[i]) q.push(i);
while (!q.empty()) {
int u = q.front(); q.pop();
tr[tr[u].fail].endp = tr[u].endp;
if (!--indgr[tr[u].fail]) q.push(tr[u].fail);
}
for (int i = 2; i <= idx; ++ i)
G[tr[i].fail][s[tr[i].endp + tr[tr[i].fail].len] - '0'] = i;
}
inline void dfs(int u = 1) {
if (!u) return;
if (tr[u].edp) sa[++ ct] = tr[u].edp;
dfs(G[u][0]); dfs(G[u][1]);
}
}SAM;
int main()
{
scanf ("%d%d", &n, &K);
scanf ("%s", s + 1);
// 不翻转
memcpy(t[0], s, sizeof(s));
int l = 1, r = n, lst = K;
while (lst) {
while (l <= r && t[0][l] == '0') ++ l;
while (l <= r && t[0][r] == '1') -- r;
if (l >= r) break;
-- lst, swap(t[0][l], t[0][r]);
}
// 翻转
reverse(s + 1, s + n + 1); SAM.Init();
for (int i = n; i; -- i) SAM.Insert(s[i] - 'a', i);
SAM.Build(); SAM.dfs(); -- K;
for (int i = 1; i <= n; ++ i) pre[i] = pre[i - 1] + (s[i] & 1);
L = n;
for (int l = 1, r = 1; l <= n; ++ l) {
while (r <= n) {
int c1 = pre[n] - pre[r] + pre[l - 1], c0 = (r - l + 1) - pre[r] + pre[l - 1];
if (c1 <= K && c1 <= c0) {
L = min(L, r - l + 1);
break;
} ++ r;
}
}
for (int i = 1; i <= n; ++ i) {
int l = sa[i], r = sa[i] + L - 1;
int c1 = pre[n] - pre[r] + pre[l - 1], c0 = (r - l + 1) - pre[r] + pre[l - 1];
if (c1 <= K && c1 <= c0) {
for (int i = 1; i <= n - L; ++ i) t[1][i] = '0';
for (int i = n, j = r; j >= l; -- i, -- j) {
if (s[j] == '1') t[1][i] = '1';
else t[1][i] = (c1 > 0) + '0', -- c1;
}
break;
}
}
for (int i = 1; i <= n; ++ i) {
if (t[0][i] < t[1][i]) { better = 0; break; }
if (t[1][i] < t[0][i]) { better = 1; break; }
}
for (int i = 1; i <= n; ++ i)
ans = ((ans << 1) | (t[better][i] & 1)) % Mod;
return printf ("%d\n", ans), 0;
}