求助 RE ( UB ?
  • 板块灌水区
  • 楼主haochengw920
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/5/16 22:40
  • 上次更新2024/5/17 13:33:07
查看原帖
求助 RE ( UB ?
563650
haochengw920楼主2024/5/16 22:40

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; 
}
2024/5/16 22:40
加载中...