LY1162 [ 20230323 CQYC省选模拟赛 T3 ] 跳!跳!跳!

cxqghzj·2024-03-06 09:10·8 次阅读

LY1162 [ 20230323 CQYC省选模拟赛 T3 ] 跳!跳!跳!

题意#

给定 n 个长度为 m 的字符串,进行若干操作,求每个字符串 SaSb 的方案数。

另外,你还有一个模式串 T,由 1,...,n0(通配符) 组成。

  • Sx 右边的串开始,不断向右移动,直到 SyT 匹配。
  • Sx 左边的串开始,不断向左移动,直到 SyT 匹配。
  • T 任意一个字符为 0 的位置改为 1,...,n。从当前串开始,不断往右移动,直到 SyT 匹配。
  • T 任意一个字符改为 0,不移动。

m5,n500

Sol#

trivial 地,考虑如何用一个状态表示当前的 T

不难发现当前 T 一定和 Sx 匹配,那么我们只需要状压记录当前 T 哪些位置是 0 就行了。

考虑对于每个起点跑 bfs

前两个操作可以简单预处理,而第三个操作需要 n×m 的复杂度进行转移。

总复杂度为 n32mm

直接卡常草过去。

Code#

Copy
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") #include <iostream> #include <algorithm> #include <cstdio> #include <array> #include <queue> #include <vector> #include <bitset> /* #define int long long */ #define pii pair <int, int> #define il inline #define rg register using namespace std; #ifdef ONLINE_JUDGE #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++) char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf; #endif il int read() { rg int p = 0, flg = 1; rg char c = getchar(); while (c < '0' || c > '9') { if (c == '-') flg = -1; c = getchar(); } while (c >= '0' && c <= '9') { p = p * 10 + c - '0'; c = getchar(); } return p * flg; } void write(int x) { if (x < 0) { x = -x; putchar('-'); } if (x > 9) { write(x / 10); } putchar(x % 10 + '0'); } bool _stmer; #define fi first #define se second const int N = 505, M = 6, K = 1 << 5; array <array <int, M>, N> s; array <array <int, K>, N> pre, suf; il bool check(int T, int m, int x, int y){ rg bool flg = 1; for (rg int k = 1; k <= m; k++) if (!(T & (1 << (k - 1)))) flg &= (s[x][k] == s[y][k]); return flg; } array <array <array <vector <int>, M>, K>, N> isl; array <array <int, K>, N> dis; queue <pii> q; il void bfs(int st, int n, int m) { for (int i = 1; i <= n; i++) dis[i].fill(-1); for (int i = 0; i < 1 << m; i++) q.push(make_pair(st, i)), dis[st][i] = 0; while (!q.empty()) { rg pii u = q.front(); q.pop(); if (!~dis[pre[u.fi][u.se]][u.se]) dis[pre[u.fi][u.se]][u.se] = dis[u.fi][u.se] + 1, q.push(make_pair(pre[u.fi][u.se], u.se)); if (!~dis[suf[u.fi][u.se]][u.se]) dis[suf[u.fi][u.se]][u.se] = dis[u.fi][u.se] + 1, q.push(make_pair(suf[u.fi][u.se], u.se)); for (rg int i = 1; i <= m; i++) { int tp = u.se ^ (1 << (i - 1)); if (!~dis[u.fi][tp]) dis[u.fi][tp] = dis[u.fi][u.se] + 1, q.push(make_pair(u.fi, tp)), tot++; if (u.se & (1 << (i - 1))) continue; for (auto t : isl[u.fi][u.se][i]) { if (~dis[t][tp]) continue; dis[t][tp] = dis[u.fi][u.se] + 1; q.push(make_pair(t, tp)); } } } } array <array <int, N>, N> ans; array <bitset <N>, M> vis; bool _edmer; int main() { cerr << (&_stmer - &_edmer) / 1024.0 / 1024.0 << "MB\n"; /* freopen("string.in", "r", stdin); */ /* freopen("string.out", "w", stdout); */ rg int n = read(), m = read(); for (rg int i = 1; i <= n; i++) for (rg int j = 1; j <= m; j++) s[i][j] = read(); for (rg int i = 1; i <= n; i++) { for (rg int T = 0; T < 1 << m; T++) { for (rg int j = 1; j < n; j++) { if (check(T, m, i, (i - j + n - 1) % n + 1)) { pre[i][T] = (i - j + n - 1) % n + 1; break; } } for (rg int j = 1; j < n; j++) { if (check(T, m, i, (i + j - 1) % n + 1)) { suf[i][T] = (i + j - 1) % n + 1; break; } } for (rg int j = 1; j <= m; j++) vis[j] = 0, vis[j][s[i][j]] = 1; for (rg int j = 1; j < n; j++) { rg int t = (i + j - 1) % n + 1; for (rg int k = 1; k <= m; k++) if (check(T, m, i, t) && (T & (1 << (k - 1))) && !vis[k][s[t][k]]) isl[t][T ^ (1 << (k - 1))][k].push_back(i), vis[k][s[t][k]] = 1; } } } for (rg int i = 1; i <= n; i++) { bfs(i, n, m); for (rg int j = 1; j <= n; j++) ans[j][i] = dis[j][(1 << m) - 1]; } for (rg int i = 1; i <= n; i++) { for (rg int j = 1; j <= n; j++) write(ans[i][j]), putchar(32); puts(""); } return 0; }
posted @   cxqghzj  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示
目录