当前位置: 首页 > news >正文

CF2161H Cycle Sort

先把序列转 01,考虑对 01 序列编一些做法。

这里造成修改只能是 \(a_{t\bmod n}=1,b_{t\bmod m}=0\),于是我们可以直接扔掉 \(a=0\)\(b=1\) 的位。剩下每个 \(b_j=1\),就是对于 \(t=j+cM\),都有可能使 \(a_{t\bmod n}\leftarrow 0\),对于一个 \(j\),这样的修改只能进行一次。特别地,如果 \(a_i=0\),我们认为有一个 \(t=-\infty\) 的修改。

一个想法是把这些修改挂到每个 \(a\) 上。具体地,对于初始 \(b_j=1\),将修改挂到 \(j\bmod n\) 上。然后每次对于一个点 \(i\),如果其上有 \(\ge 2\) 个标记,就把除最小值外的推到 \((i+m)\bmod n\),并且把修改的时间 \(+m\)。如果一个修改的时间 \(\ge K\),那么说明这个是不会有影响的,就可以直接确定 \(b=0\)。不妨把序列按 \(\bmod \gcd(n,m)\) 分类,然后按照 \(0,m\bmod n,\cdots,((n-1)m)\bmod n\) 的顺序重排,这样每次就是往后 \((i+1)\bmod n\)

然后考虑怎么动态做。每次变化是把一个 \(1\to 0\),也就是新增一个修改。可以发现,如果原来一个修改最终时刻会被推到 \(\ge K\),那么它在之后也没用了。

考虑维护出所有有用的修改。记 \(c_i\) 为有多少个修改一开始被放在 \(i\),那么向后推就是在做类似括号匹配的东西。取出前缀和 \(s_i=\sum\limits_{j\le i}(c_j-1)\),整个序列会被非严格前缀 \(\min\) 划分为若干段,每段 \([l,r]\) 内是匹配的括号序列。同时可以发现,\(l\) 中时间最大的修改一定会被推到 \(r\) 匹配。

那么对于一个新增的修改,可以把它直接加入,判一下所在的段是否满足条件,不满足条件时把左端点处的时间最大的修改删除即可。这个可以线段树维护。复杂度 \(O(n\log n)\)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;const int inf = 1e9;
const int kN = 2e5 + 5, kS = kN * 12;
int n, m, L;
ll K;
int a[kN], b[kN], c[kN], d[kN];
int va[kN], vb[kN], vc[kN], vd[kN];
int na[kN], rk[kN], ord[kN];
priority_queue<int> q[kN];struct Info {int mn, id;Info() { mn = 0, id = -1; }Info(int _mn, int _id) {mn = _mn;id = _id;}
};
Info operator + (Info x, Info y) {return Info(min(x.mn, y.mn),max((x.mn <= y.mn) ? x.id : -inf,(x.mn >= y.mn) ? y.id : -inf));
}#define ls (o << 1)
#define rs (o << 1 | 1)struct SGT {Info info[kS];int tag[kS];void Up(int o) { info[o] = info[ls] + info[rs]; }void Adt(int o, int t) { info[o].mn += t, tag[o] += t; }void Dn(int o) {if(int &t = tag[o]) {Adt(ls, t), Adt(rs, t), t = 0;}}void Init(int o, int l, int r) {tag[o] = 0;if(l == r) return void(info[o] = Info(-1 - l, l));int mid = (l + r) >> 1;Init(ls, l, mid);Init(rs, mid + 1, r);Up(o);}void Update(int o, int l, int r, int x, int y, int v) {if((l > y) || (r < x)) return ;if((l >= x) && (r <= y)) return Adt(o, v);Dn(o);int mid = (l + r) >> 1;Update(ls, l, mid, x, y, v);Update(rs, mid + 1, r, x, y, v);Up(o);}Info Query(int o, int l, int r, int x, int y) {if((l > y) || (r < x)) return Info(0, -1);if((l >= x) && (r <= y)) return info[o];Dn(o);int mid = (l + r) >> 1;return Query(ls, l, mid, x, y) + Query(rs, mid + 1, r, x, y);}int Find(int o, int l, int r, int x, int v) {if(info[o].mn > v) return r + 1;if(l == r) return r;Dn(o);int mid = (l + r) >> 1;if(mid < x) return Find(rs, mid + 1, r, x, v);int lft = Find(ls, l, mid, x, v);return (lft > mid) ? Find(rs, mid + 1, r, x, v) : lft;}
} sgt;void Work(int n, int m, int *a, int *b, int *c, int *d, ll K) {L = n + n + n;sgt.Init(1, 0, L);fill_n(q, n, priority_queue<int> ());for(int i = 0; i < n; i++) {int p = (ll)i * m % n;na[i] = a[p];rk[p] = i;ord[i] = p;}vector<pair<int, int>> vec;for(int i = 0; i < n; i++) {vec.emplace_back(a[i], i);}for(int i = 0; i < m; i++) {vec.emplace_back(b[i], i + n);}sort(vec.begin(), vec.end());auto Update = [&](int p, int v) {sgt.Update(1, 0, L, p, L, v);sgt.Update(1, 0, L, p + n, L, v);sgt.Update(1, 0, L, p + n + n, L, v);};auto AddToken = [&](int p, int tok) -> int {q[p].push(tok);Update(p, 1), p += n;Info info = sgt.Query(1, 0, L, 0, p - 1);int l = info.id + 1;int r = sgt.Find(1, 0, L, l, info.mn);int top = q[l % n].top();if((r <= L) && ((top == -inf) || (top + (ll)(r - l) * m < K))) {return -1 - r;}q[l % n].pop();Update(l % n, -1);return top;};for(auto k : vec) {int val, id, sq = 0;tie(val, id) = k;if(id >= n) id -= n, sq = 1;int p, tok;if(!sq) {p = rk[id], tok = -inf;}else {p = rk[id % n], tok = id;}int v = AddToken(p, tok);if(v >= 0) d[v] = val;else c[ord[(-1 - v) % n]] = val;}
}void Solve() {cin >> n >> m >> K;for(int i = 0; i < n; i++) cin >> a[i];for(int i = 0; i < m; i++) cin >> b[i];int g = __gcd(n, m);for(int r = 0; r < g; r++) {int cn = 0, cm = 0;for(int i = r; i < n; i += g) va[cn++] = a[i];for(int i = r; i < m; i += g) vb[cm++] = b[i];Work(cn, cm, va, vb, vc, vd, K / g + (K % g > r));for(int i = 0, j = r; i < cn; i++, j += g) {c[j] = vc[i];}for(int i = 0, j = r; i < cm; i++, j += g) {d[j] = vd[i];}}for(int i = 0; i < n; i++) {cout << c[i] << " \n" [i == n - 1];}for(int i = 0; i < m; i++) {cout << d[i] << " \n" [i == m - 1];}
}int main() {// freopen("1.in", "r", stdin);// freopen("1.out", "w", stdout);ios::sync_with_stdio(0), cin.tie(0);int t;cin >> t;while(t--) Solve();return 0;
}
http://www.rkmt.cn/news/81474.html

相关文章:

  • (2025年)喷雾剂灌装机哪些品牌好、哪家口碑好、哪家品质好、哪家公司好 - 品牌推荐大师
  • 上海实邦电子:以嵌入式开发为核心,赋能产品智能化升级 - 速递信息
  • 2025国内稳定性较好的、灵敏度高的、智能高效的镀层检测生产商/知名品牌/优质厂家排名/靠谱厂家/推荐品牌/头部企业 - 品牌推荐大师1
  • 2025年黑龙江自闭症学校机构权威榜单:黑龙江孤独症学校/黑龙江自闭症康复学校/黑龙江孤独症康复学校推荐指南 - 品牌推荐官
  • 2025年本地环氧地坪商家排行,看谁的大理石翻新养护更出色,可靠的大理石翻新养护忠博盛涛保洁专注产品质量 - 品牌推荐师
  • python _—— 使用hash函数实现一种类似字典的简易hash存储结构
  • 2025年ai收银机源头厂家推荐榜单:收银机收款‌/银行收银机‌/餐饮收银机一体机源头厂家精选 - 品牌推荐官
  • 2025 年湖南湘潭排油烟工程厂家最新推荐榜,技术实力与市场口碑深度解析消防工程/洁净工程/恒温恒湿工程/通风工程公司推荐 - 品牌鉴赏师
  • 2025年车铣复合加工订做厂家权威推荐榜单:插针加工厂/电极供货厂/航空插头源头厂家精选 - 品牌推荐官
  • 2025年靠谱学术会议服务公司推荐!学术研讨会/学术年会/学术交流会/学术峰会/合肥学术会议策划公司 - 麦麦唛
  • Python - 笔记
  • 使用 LangChain 搭建一个 AI Agent:从零到可运行 Demo
  • 净化车间制造厂家2025最新榜单出炉!无锡新源环保引领行业新标杆! - 深度智识库
  • 2025 年 12 月实验室整体解决方案实力推荐:涵盖实验室规划设计、实验室装修、实验台通风柜定制集成一站式服务,源头工厂专业可靠高效省心 - 深度智识库
  • 【2025权威发布】长轴液下泵|不锈钢液下泵|不锈钢化工泵|衬氟磁力泵|自吸磁力泵哪个厂家品质口碑好,知名企业品牌排行——亚梅泵业出众 - 品牌推荐大师1
  • 海外仓WMS系统选型:自研vsSaaS模式,企业该怎么选?
  • 2025年毛绒玩具除尘机工厂权威推荐榜单:毛绒玩具吹毛机/玩具行业封箱打包机/封箱打包机源头厂家精选 - 品牌推荐官
  • 2025年铁基催化剂生产厂家权威推荐榜单:沼气脱硫剂/高效脱硫剂/煤气脱硫催化剂源头厂家精选 - 品牌推荐官
  • 2025年真空皮带过滤机源头厂家推荐榜单:橡胶真空过滤机‌/水平真空过滤机‌/水平带式过滤机源头厂家精选 - 品牌推荐官
  • 完整教程:多智能体框架AgentScope 1.0 深度技术剖析:架构、场景、选型与实战指南
  • 洛谷 P3706
  • UniTask如何做到“零分配”
  • 2025年潮州凤凰单丛茶品牌口碑推荐榜单以及全面解析 - 讯息观点
  • 如何实现 vxe-tree 树组件拖拽节点后进行二次确认提示
  • SecureCRT SecureFX 9.7 for macOS, Linux, Windows - 跨平台的多协议终端仿真和文件传输
  • PostgreSQL 19:超高速聚合的全新突破
  • pycharm2025.3 12月最新 安装、授权、使用说明
  • GL980/GL2000/GL7000/USB蓝牙冷链温度记录仪选购指南:优质品牌、口碑厂家及供应商推荐 - 品牌推荐大师
  • 国标GB28181算法算力平台EasyGBS港口智能化监控解决方案
  • 2025年行业内知名的金属探测门品牌推荐,目前评价好的金属探测门推荐10年质保有保障 - 品牌推荐师