隐藏页面特效

The 1st Universal Cup. Stage 20: India

1|0Preface


久违的训练,然后选了场题目贼诡异的场,牢底坐穿了

这场最大的问题就是一个被过穿的了 Counting 一直出不来,然后 B 卡了贼久,N 帮祁神写了个特判结果还写漏了一个 Case,直接演完了

封榜后出了另一个构造,结果还是不会 G,最后看题解是个听都没听过的东西,这下是死透了


2|0B. Minimize Median


思路很一眼的题,但一些神秘细节比较坑人,挂了好多发才艹过去

首先根据经典结论 xab=xab,我们可以先求出 fi 表示乘积为 i 的最小代价

然后中位数问题一眼考虑二分答案 mid,要检验的话需要求出将至少 n+12 个数变为 mid 的最小代价

贪心地想一下肯定是操作最小的 n+12 个数最优,并且如果我们要将 ai 变为 mid,最少要除的数为 aimid+1+1,简单处理一下即可

预处理 fi 数组时需要注意超出 m 部分的处理,总复杂度 O((n+m)logm)

#include <bits/stdc++.h> using llsi = long long signed int; llsi a[1000006], cost[1000006], dp[1000006]; llsi solve(int n, llsi mid) { n = (n + 1) / 2; llsi res = 0; if(mid == 0) for(int i = 1; i <= n; ++i) res += dp[a[i] + 1]; else for(int i = 1; i <= n; ++i) { if(a[i] <= mid) continue; res += dp[a[i] / (mid + 1) + 1]; } return res; } void work() { llsi n, m, k; std::cin >> n >> m >> k; for(int i = 1; i <= n; ++i) std::cin >> a[i]; for(int i = 1; i <= m; ++i) std::cin >> cost[i]; for(int i = m - 1; i >= 1; --i) cost[i] = std::min(cost[i], cost[i + 1]); for(int i = 2; i <= m + 1; ++i) dp[i] = 0X0D00072100114514LL; for(int i = 1; i <= m; ++i) for(int j = 1; j <= m; ++j) { if(i * j <= m) dp[i * j] = std::min(dp[i * j], dp[i] + cost[j]); else { dp[m + 1] = std::min(dp[m + 1], dp[i] + cost[j]); break; } } for(int i = m; i >= 1; --i) dp[i] = std::min(dp[i], dp[i + 1]); // for(int i = 1; i <= m; ++i) std::cerr << cost[i] << char(i == m ? 10 : 32); std::sort(a + 1, a + n + 1); llsi l = 0, r = m; while(l < r) { llsi mid = (l + r) >> 1; if(solve(n, mid) <= k) r = mid; else l = mid + 1; } // std::cerr << solve(n, 3) << char(10); std::cout << l << char(10); } int main() { std::ios::sync_with_stdio(false); int T; std::cin >> T; while(T--) work(); return 0; }

3|0D. Central Subset


队友开局讨论的,我题目都不知道

#include<bits/stdc++.h> using namespace std; const int N = 2e5+5; int n, m, deg[N], dis[N]; //dis1[N], dis2[N]; int que[N], ed=-1, fr=0; bool vis[N]; vector<int> G[N], nG[N]; void dfs1(int x) { vis[x] = true; for (auto v : G[x]) { if (vis[v]) continue; nG[x].push_back(v); nG[v].push_back(x); ++deg[x]; ++deg[v]; dfs1(v); } } // int dfs2(int x, int f, int dis[]) { // int res = x; // for (auto v : nG[x]) { // if (v==f) continue; // dis[v] = dis[x] + 1; // int tmp = dfs2(v, x, dis); // if (dis[tmp] > dis[res]) res = tmp; // } // return res; // } void solve() { cin >> n >> m; for (int i=1; i<=n; ++i) G[i].clear(), nG[i].clear(), vis[i]=false, dis[i]=0, deg[i]=0; for (int i=1; i<=m; ++i) { int u, v; cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } dfs1(1); // printf("deg:"); for (int i=1; i<=n; ++i) printf("%d ", deg[i]); puts(""); ed=-1, fr=0; for (int i=1; i<=n; ++i) { if (1==deg[i]) que[++ed] = i; vis[i] = false; } int sqr = (int)sqrtl(n); // printf("sqr=%d\n", sqr); if (sqr*sqr < n) ++sqr; vector<int> ans; while (fr<=ed) { int x = que[fr++]; vis[x]=true; if (dis[x]==sqr) ans.push_back(x), dis[x]=-1; bool ok=false; for (int v : nG[x]) if (!vis[v]) { ok=true; --deg[v], --deg[x]; dis[v] = max(dis[v], dis[x]+1); if (1==deg[v]) que[++ed] = v; } if (!ok) ans.push_back(x); // printf("x=%d vis:", x); for (int i=1; i<=n; ++i) printf("%d ", vis[i]); puts(""); // printf("x=%d dis:", x); for (int i=1; i<=n; ++i) printf("%d ", dis[i]); puts(""); // printf("x=%d deg:", x); for (int i=1; i<=n; ++i) printf("%d ", deg[i]); puts(""); } // puts("111111"); // dis1[1] = 0; int x = dfs2(1, -1, dis1); // dis1[x] = 0; int y = dfs2(x, -1, dis1); // dis2[y] = 0; dfs2(y, -1, dis2); // printf("x=%d y=%d\n", x, y); // printf("dis2:"); for (int i=1; i<=n; ++i) printf("%d ", dis2[i]); puts(""); // for (int i=1; i<=n; ++i) { // if (dis1[i]+dis2[i]==dis1[y] && dis1[i]%sqr==0) ans.push_back(i); // } sort(ans.begin(), ans.end()); ans.erase(unique(ans.begin(), ans.end()), ans.end()); cout << ans.size() << '\n'; for (int x : ans) cout << x << ' '; cout << '\n'; } signed main() { ios::sync_with_stdio(0); cin.tie(0); int t; cin >> t; while (t--) solve(); return 0; }

4|0F. Longest Strictly Increasing Sequence


首先注意到 bibi1 的值只能是 0/1,因此最后合法的整个序列一定形如 1,2,2,2,3,3,4,4,5

那么值相同的一段倒着放即可,比如上面那个例子可以放 1,4,3,2,6,5,8,7,9

#include<cstdio> #include<iostream> #define RI register int #define CI const int& using namespace std; const int N=15; int t,n,a[N],ans[N],L[N],R[N]; int main() { for (scanf("%d",&t);t;--t) { scanf("%d",&n); for (RI i=1;i<=n;++i) scanf("%d",&a[i]); bool flag=(a[1]==1); for (RI i=1;i<n;++i) if (a[i+1]-a[i]!=0&&a[i+1]-a[i]!=1) { flag=0; break; } if (!flag) { puts("NO"); continue; } for (RI i=1;i<=10;++i) L[i]=n+1,R[i]=0; for (RI i=1;i<=n;++i) L[a[i]]=min(L[a[i]],i),R[a[i]]=max(R[a[i]],i); int idx=0; for (RI i=1;i<=10;++i) for (RI j=R[i];j>=L[i];--j) ans[j]=++idx; puts("YES"); for (RI i=1;i<=n;++i) printf("%d%c",ans[i]," \n"[i==n]); } return 0; }

5|0K. XOR Dice


思博题

一个 naive 的想法就是每个骰子都放 0,d,d×26,d×212,d×218,d×224,但这样会超出上界

不过后面徐神发现其实不用单纯的 shift,将某些情况组合在一起也是可以的,一种合法的方案是使用 0,d,d×26,d×212,d×(26+1),d×(212+1)

#include<cstdio> #include<iostream> #define RI register int #define CI const int& using namespace std; int n,d; int main() { scanf("%d%d",&n,&d); for (RI i=1;i<=n;++i) printf("%d %d %d %d %d %d\n",0,d,d*(1<<6),d*(1<<12),d*((1<<6)+1),d*((1<<12)+1)); return 0; }

6|0L. (1, 2) Nim


看的博弈先 Rush 个暴力上去,打表发现以下规律:

  • 当存在 2 个非 1 的堆时,先手必败;
  • 当存在恰好一个非 1 的堆时,先手获胜当且仅当 nmod32
  • 不存在非 1 的堆时,先手获胜当且仅当 nmod3=1

证明可以用归纳法,但我只能说打表 yyds

#include<cstdio> #include<iostream> #define RI register int #define CI const int& using namespace std; int t,n,x; int main() { for (scanf("%d",&t);t;--t) { scanf("%d",&n); int cnt=0; for (RI i=1;i<=n;++i) scanf("%d",&x),cnt+=(x>1); if (cnt>=2) puts("Grundy"); else if (cnt==1) puts(n%3!=2?"Sprague":"Grundy"); else puts(n%3==1?"Sprague":"Grundy"); } return 0;

7|0M. Graphs and Colors


思路很顺畅的一个题

首先由于每种颜色要将图连通,因此至少要 n1 条边,故 k>n2 时一定无解

现在考虑对 k=n2 构造一种合法方案,因为对于 k<n2 的情形我们可以修改其中的一些颜色为 1 来得到一个依旧合法的解

先考虑 n 为偶数的情况,将所有点两两配对,如 (2i1,2i) 间连颜色为 i 的边

对于两个点对 1i<j<n2,在 (2i1,2j1),(2i,2j) 间连颜色为 i 的边,在 (2i1,2j),(2i,2j1) 间连颜色为 j 的边,手玩下会发现这样一定合法

对于 n 为奇数的情况,先求出前 n1 个点的一组合法解,然后把 n 和每个点对用对应的颜色连通即可

#include<bits/stdc++.h> using namespace std; const int N = 105; int edg[N][N]; void solve() { int n, k; cin >> n >> k; if (k>n/2) { cout << "NO\n"; return ; } for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) edg[i][j] = 0; auto inv = [&](int a) {return n+1-a;}; for (int c=1; c<=n/2; ++c) { edg[c][inv(c)] = c; for (int i=1; i<c; ++i) edg[c][inv(i)] = c, edg[i][inv(c)] = c; for (int i=c+1; i<=n/2; ++i) edg[c][i] = c, edg[inv(i)][inv(c)] = c; } if (n%2==1) { for (int i=1; i<=n/2; ++i) edg[i][(n+1)/2] = i, edg[(n+1)/2][inv(i)] = i; } cout << "YES\n"; for (int i=2; i<=n; ++i) { for (int j=1; j<i; ++j) { if (edg[j][i]>k) edg[j][i] = 1; cout << edg[j][i] << ' '; } cout << '\n'; } } signed main() { ios::sync_with_stdio(0); cin.tie(0); int t; cin >> t; while (t--) solve(); return 0; }

8|0N. Red Black Grid


这场好多构造啊,贵国是构造王国吗.jpg

首先考虑特判 n3 的情况,同时不难发现 k=1k=2×n×(n1)1 时一定无解

否则考虑进行一个棋盘染色,先假设整个棋盘都是 R,然后钦定只有 i+j 为偶数的位置能把 R 翻转成 B

此时我们相当于获得了贡献为 2,3,4 的位置,要用它们拼凑出 k 的权值,讨论下会发现先用大的再用小的,配合上一些回退操作,一定可以表示出所有情况

#include<bits/stdc++.h> using namespace std; using pii = pair<int, int>; const int N = 1005; int tbl[N][N]; void solve() { int n, k; cin >> n >> k; int tmpk = k; if (1==k || 2*n*(n-1) - 1 == k) { cout << "Impossible\n"; return; } if (1==n) { if (k==0) { cout << "Possible\n"; cout << "R\n"; } else cout << "Impossible\n"; } else if (2==n) { if (k==0) { cout << "Possible\n"; cout << "RR\nRR\n"; } else if (k==2) { cout << "Possible\n"; cout << "BR\nRR\n"; } else if (k==4) { cout << "Possible\n"; cout << "BR\nRB\n"; } else cout << "Impossible\n"; } else if (3==n) { if (k==0) { cout << "Possible\n"; cout << "RRR\nRRR\nRRR\n"; } else if (k==2) { cout << "Possible\n"; cout << "BRR\nRRR\nRRR\n"; } else if (k==3) { cout << "Possible\n"; cout << "RBR\nRRR\nRRR\n"; } else if (k==4) { cout << "Possible\n"; cout << "RRR\nRBR\nRRR\n"; } else if (k==5) { cout << "Possible\n"; cout << "RRB\nRRR\nRBR\n"; } else if (k==6) { cout << "Possible\n"; cout << "RBR\nRRR\nRBR\n"; } else if (k==7) { cout << "Possible\n"; cout << "RBR\nRRR\nBRB\n"; } else if (k==8) { cout << "Possible\n"; cout << "BRB\nRRR\nBRB\n"; } else if (k==9) { cout << "Possible\n"; cout << "RBR\nRRB\nRBR\n"; } else if (k==10) { cout << "Possible\n"; cout << "BRB\nRBR\nRRB\n"; } else if (k==12) { cout << "Possible\n"; cout << "BRB\nRBR\nBRB\n"; } else cout << "Impossible\n"; } else { vector<pii> pos2, pos3, pos4; for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) if ((i+j)%2==0) { if (i!=1 && i!=n && j!=1 && j!=n) pos4.push_back({i, j}); else { if ((i==1 || i==n) && (j==1 || j==n)) pos2.push_back({i, j}); else pos3.push_back({i, j}); } } int sz2=pos2.size(); int sz3=pos3.size(); int sz4=pos4.size(); vector<pii> ans; if (k/4 <= sz4) { for (int i=0; i<k/4; ++i) ans.push_back(pos4[i]); if (k%4 == 1) ans.pop_back(), ans.push_back(pos2[0]), ans.push_back(pos3[0]); else if (k%4 == 2) ans.push_back(pos2[0]); else if (k%4 == 3) ans.push_back(pos3[0]); } else { ans = pos4; if (4*sz4+1 == k) ans.push_back({1, 2}); else { k -= 4*sz4; int bd = (n%2==0 ? 2 : 4); for (int i=0; i<=bd; ++i) { if ((k-2*i)%3==0 && (k-2*i)/3 <= sz3) { for (int j=0; j<i; ++j) ans.push_back(pos2[j]); for (int j=0; j<(k-2*i)/3; ++j) ans.push_back(pos3[j]); break; } } } } cout << "Possible\n"; for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) tbl[i][j] = 0; for (auto [r, c] : ans) tbl[r][c] = 1; int tmp=0; for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) { if (i-1>=1 && tbl[i-1][j] != tbl[i][j]) ++tmp; if (i+1<=n && tbl[i+1][j] != tbl[i][j]) ++tmp; if (j-1>=1 && tbl[i][j-1] != tbl[i][j]) ++tmp; if (j+1<=n && tbl[i][j+1] != tbl[i][j]) ++tmp; } tmp /= 2; // printf("tmp=%d\n", tmp); assert(tmp==tmpk); for (int i=1; i<=n; ++i) { for (int j=1; j<=n; ++j) cout << (tbl[i][j] == 0 ? 'B' : 'R'); cout << '\n'; } } } signed main() { ios::sync_with_stdio(0); cin.tie(0); int t; cin >> t; while (t--) solve(); return 0; }

9|0Postscript


感觉今天这场啥也没写就结束了,估计是起的太早导致全程犯困,看来得好好调整下生物钟了的说


__EOF__

本文作者hl666
本文链接https://www.cnblogs.com/cjjsb/p/18438112.html
关于博主:复活的ACM新生,目前爱好仅剩Gal/HBR/雀魂/单机/OSU
版权声明:转载请注明出处
声援博主:欢迎加QQ:2649020702来DD我
posted @   空気力学の詩  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2023-09-28 Educational Codeforces Round 155 (Rated for Div. 2)
2018-09-28 BZOJ 4804: 欧拉心算
点击右上角即可分享
微信分享提示