[考试记录] 2024.11.16 noip模拟赛14
T1 字符串构造机
考虑将一个 LCP 条件拆分成两个,一个是相等的部分,使用并查集维护,另一个是不等的部分,两个串末尾的字符一定不相等,随便那啥维护。对于非法情况就是在同一个相等联通块内有不相等的条件。然后考虑从前往后贪心即可。
#include<bits/stdc++.h> using namespace std; #define p pair<int, int> constexpr int N = 1e3 + 5; int n, m, s[N], f[N], g[N][2], tot; inline int find(int k){ return f[k] ? f[k] = find(f[k]) : k; } vector<int> G[N]; bitset<N> st; int main(){ freopen("str.in", "r", stdin); freopen("str.out", "w", stdout); ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); cin>>n>>m; for(int i=1, x, y, z; i<=m; ++i){ cin>>x>>y>>z; if(x > y) swap(x, y); int l1 = x, l2 = y, r1 = x+z-1, r2 = y+z-1; if(x == y) continue; if(r2+1 <= n) g[++tot][0] = r1+1, g[tot][1] = r2+1; for(int u=l2, v=l1; u<=r2; ++u, ++v){ int fa = find(u), fb = find(v); if(fa == fb) continue; f[fa] = fb; } } memset(s, 0xff, sizeof(int) * (n+1)); for(int i=1; i<=tot; ++i){ int u = find(g[i][0]), v = find(g[i][1]); if(u == v) return cout<<"-1", 0; G[u].push_back(v), G[v].push_back(u); } for(int i=1; i<=n; ++i){ int fa = find(i); if(s[fa] == -1){ st.reset(); for(int v : G[fa]) if(s[find(v)] != -1) st[s[find(v)]] = 1; int cnt = 0; while(st[cnt]) ++cnt; s[fa] = cnt; } s[i] = s[fa]; } for(int i=1; i<=n; ++i) cout<<s[i]<<' '; return 0; }
T2 忍者小队
最大值是简单的。找到所有 的倍数并取个 gcd,如果这个 gcd 不为 ,那么不存在合法的最大最小。否则最大值就为倍数的数量。
考虑最小值答案值域,一定为 。因为最多质数组成数最大仅为 。那么令 表示有 个数 gcd 为 的方案数。考虑容斥,有:
其中 为倍数数量。用方案数来 check 即可。
#include<bits/stdc++.h> using namespace std; constexpr int N = 3e5 + 5, M = 1e9 + 7; int n, m, a[N], val[N], mx, f[8][N], ans[N][2], C[N][8], tot[N]; inline int add(initializer_list<int> Add){ int res = 0; for(int v : Add) res = res + v >= M ? res + v - M : res + v; return res; } int main(){ freopen("sor.in", "r", stdin); freopen("sor.out", "w", stdout); ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); cin>>n>>m; for(int i=1; i<=n; ++i) cin>>a[i], ++val[a[i]], mx = max(mx, a[i]); for(int i=0; i<=n; ++i) C[i][0] = 1; for(int i=1; i<=n; ++i) for(int j=1; j<=7; ++j) C[i][j] = add({C[i-1][j], C[i-1][j-1]}); for(int i=1; i<=mx; ++i) ans[i][0] = 114514; for(int k=1; k<=mx; ++k){ int tmp = 0, sum = 0; for(int i=1; i*k<=mx; ++i) if(val[i*k]) tmp = __gcd(tmp, i), sum += val[i*k]; tot[k] = sum; if(tmp ^ 1) { ans[k][1] = ans[k][0] = -1; continue; } ans[k][1] = sum; if(val[k]) ans[k][0] = 1; } for(int k=mx; k>=1; --k){ for(int i=1; i<=7; ++i){ f[i][k] = C[tot[k]][i]; for(int j=k*2; j<=mx; j+=k) f[i][k] = add({f[i][k], M-f[i][j]}); if(f[i][k] && ans[k][0] == 114514) ans[k][0] = i; } } for(int i=1; i<=m; ++i) cout<<ans[i][0]<<' '<<ans[i][1]<<'\n'; return 0; }
T3 狗卡
来不及写了……👀
#include<bits/stdc++.h> using namespace std; constexpr int B = 1 << 15; char buf[B], *p1 = buf, *p2 = buf; #define gt() (p1==p2 && (p2=(p1=buf)+fread(buf, 1, B, stdin), p1==p2) ? EOF : *p1++) template <typename T> inline void rd(T &x){ x = 0; int f = 0; char ch = gt(); for(; !isdigit(ch); ch = gt()) f ^= ch == '-'; for(; isdigit(ch); ch = gt()) x = (x<<1) + (x<<3) + (ch^48); x = f ? -x : x; } template <typename T, typename ...TT> inline void rd(T &x, TT &...y){ rd(x), rd(y...); } constexpr int N = 1.2e6 + 5; struct Seg{ int id, l, r, len; long long sum; }; vector<int> a[N]; vector<Seg> vec; int main(){ freopen("dog.in", "r", stdin); freopen("dog.out", "w", stdout); int n; long long m; rd(n ,m); for(int i=1, k; i<=n; ++i){ rd(k); for(int j=1, x; j<=k; ++j) rd(x), a[i].emplace_back(x); vec.emplace_back(Seg{i, 0, 0, 1, a[i][0]}); for(int j=1; j<k; ++j){ Seg tmp = vec.back(); if((long long)a[i][j] * tmp.len <= tmp.sum){ vec.pop_back(); tmp.r = j, ++tmp.len, tmp.sum += a[i][j]; while(!vec.empty() && vec.back().id == i && vec.back().sum * tmp.len > tmp.sum * vec.back().len){ tmp.l = vec.back().l, tmp.len += vec.back().len, tmp.sum += vec.back().sum; vec.pop_back(); } vec.emplace_back(tmp); } else vec.emplace_back(Seg{i, j, j, 1, a[i][j]}); } } sort(vec.begin(), vec.end(), [](Seg x, Seg y){ return x.sum * y.len < y.sum * x.len; }); long long sum = 0, ans = 0; for(auto it : vec){ for(int i=it.l; i<=it.r; ++i){ ans += m - a[it.id][i] - sum; sum += a[it.id][i]; } } return printf("%lld", ans), 0; }
T4 怪盗德基
#include<bits/stdc++.h> using namespace std; int n, a[11][11], len[11], pos[11][11], f[1024][11][11][11][11]; bitset<11> ok[11][11]; inline int dfs(int s, int l, int x, int r, int y){ if(!x && y == len[r] && s == (1 << n) - 1) return 0; if(f[s][l][x][r][y] != -1) return f[s][l][x][r][y]; int res = 114; if(l < n && !x){ for(int i=0; i<n; ++i) if(!(1 & (s>>i))) for(int j=0; j<len[i]; ++j) if(ok[i][j][l]) res = min(res, dfs(s|(1<<i), i, j, r, y)); res = min(res, dfs(s, n, 0, r, y)); } for(int i=0; i<n; ++i) if(!(1 & (s>>i)) && ok[r][y][i]) res = min(res, dfs(s|(1<<i), l, x, i, 0)); for(int i=1; i<=9; ++i){ bool flag1 = x && a[l][x-1] == i, flag2 = y < len[r] && a[r][y] == i; if(flag1 && pos[r][i] <= y) res = min(res, dfs(s, l, x-1, r, y) + 1); if(flag2 && pos[l][i] <= x) res = min(res, dfs(s, l, x, r, y+1) + 1); if(flag1 && flag2) res = min(res, dfs(s, l, x-1, r, y+1) + 1); } return f[s][l][x][r][y] = res; } int main(){ freopen("hidden.in", "r", stdin); freopen("hidden.out", "w", stdout); ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); memset(pos, 0x3f, sizeof(pos)); cin>>n; for(int i=0, x, j=0; i<n; len[i]=j, j=0, ++i) while(cin>>x && x) a[i][pos[i][x] = j++] = x; for(int i=1; i<=9; ++i) pos[n][i] = 0; auto check = [&](int i, int j, int z){ for(int k=0; k<len[z]; ++k){ if(j < len[i] && pos[i][a[z][k]] == j) ++j; else if(pos[i][a[z][k]] > j) return false; } return j == len[i]; }; for(int i=0; i<n; ++i) for(int j=0; j<len[i]; ++j) for(int z=0; z<n; ++z) ok[i][j][z] = check(i, j, z); for(int i=0; i<n; ++i) ok[i][0][n] = ok[n][0][i] = true; memset(f, 0xff, sizeof(f)); int ans = 114; for(int i=0; i<n; ++i) ans = min(ans, dfs(1<<i, i, len[i], n, 0)); return cout<<(ans >= 114 ? -1 : ans), 0; }
本文作者:XiaoLe_MC
本文链接:https://www.cnblogs.com/xiaolemc/p/18549616
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步