题目大意:有一个$n \times m$的方阵,第$i$行第$j$列的人的编号是$(i-1) \times m + j$。

现在有$q$个出列操作,每次让一个人出列,然后让这个人所在行向左看齐,再让最后一列向前看齐,最后让这个人站到第$n$行第$m$列的位置。

你需要输出每次出列的人的编号。

题解:可以每行维护一棵平衡树,再给最后一列维护一棵平衡树(虽然正解是用树状数组)。

发现每行的人初始编号是连续的,而对于$9 \times 10 ^ {10}$的人数,$3 \times 10 ^ {5}$次询问改变的人数其实并不多。

所以,我们把同一行内编号连续的一段缩成一个点,然后需要出列时再分裂即可。

卡点:因为正解是树状数组,所以我洛谷被玄学卡$RE$($UOJ$过的),数组大小调了好几次,然后发现开$O(2)$,数组开的比$UOJ$大一些就不$RE$了。。。

C++ Code:(洛谷)

  1. // luogu-judger-enable-o2
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #define maxn 5500010
  5. using namespace std;
  6. struct node{
  7. int l, r;
  8. long long head;
  9. void operator -= (long long a) {l -= a; r -= a;}
  10. } val[maxn];
  11. int n, m, q;
  12. int lc[maxn], rc[maxn], num[maxn], sz[maxn], tg[maxn], idx;
  13. struct treap {
  14. int root, len;
  15. int ta, tb, tmp, tmp6;
  16. int nw(node x) {
  17. val[++idx] = x;
  18. sz[idx] = 1;
  19. num[idx] = rand();
  20. lc[idx] = rc[idx] = 0;
  21. return idx;
  22. }
  23. void update(int p) {sz[p] = sz[lc[p]] + sz[rc[p]] + 1;}
  24. void pushdown(int p) {
  25. tmp6 = tg[p]; tg[p] = 0;
  26. val[lc[p]] -= tmp6;
  27. val[rc[p]] -= tmp6;
  28. tg[lc[p]] += tmp6;
  29. tg[rc[p]] += tmp6;
  30. }
  31. void splitl(int rt, int k, int &x, int &y) {
  32. if (!rt) x = y = 0;
  33. else {
  34. if (val[rt].l <= k) splitl(rc[rt], k, rc[rt], y), x = rt;
  35. else splitl(lc[rt], k, x, lc[rt]), y = rt;
  36. update(rt);
  37. }
  38. }
  39. void splitr(int rt, int k, int &x, int &y) {
  40. if (!rt) x = y = 0;
  41. else {
  42. pushdown(rt);
  43. if (val[rt].r <= k) splitr(rc[rt], k, rc[rt], y), x = rt;
  44. else splitr(lc[rt], k, x, lc[rt]), y = rt;
  45. update(rt);
  46. }
  47. }
  48. int merge(int x, int y) {
  49. if (!x || !y) return x | y;
  50. if (num[x] > num[y]) {
  51. pushdown(x);
  52. rc[x] = merge(rc[x], y);
  53. update(x);
  54. return x;
  55. } else {
  56. pushdown(y);
  57. lc[y] = merge(x, lc[y]);
  58. update(y);
  59. return (y);
  60. }
  61. }
  62. void build(node p) {
  63. root = nw(p);
  64. }
  65. void insert(long long p, int k = -1){
  66. if (k == -1) k = len;
  67. if (!root) root = nw((node) {k, k, p});
  68. else root = merge(root, nw((node) {k, k, p}));
  69. }
  70. long long nxt(int k) {
  71. splitr(root, k - 1, ta, tmp);
  72. splitl(tmp, k, tmp, tb);
  73. int a = nw((node) {val[tmp].l, k - 1, val[tmp].head}),
  74. b = nw((node) {k + 1, val[tmp].r, val[tmp].head + k + 1 - val[tmp].l});
  75. tb = merge(b, tb);
  76. tg[tb]++;
  77. val[tb] -= 1;
  78. root = merge(merge(ta, a), tb);
  79. return k - val[tmp].l + val[tmp].head;
  80. }
  81. } s[300010], back;
  82. int main() {
  83. srand(20040826);
  84. scanf("%d%d%d", &n, &m, &q);
  85. back.len = n;
  86. for (long long i = 1; i <= n; i++) back.insert(i * m, i);
  87. for (long long i = 1; i <= n; i++) {
  88. s[i].len = m - 1;
  89. s[i].build((node){1, m - 1, (i - 1) * m + 1});
  90. }
  91. int x, y;
  92. long long ta, tb;
  93. while (q--) {
  94. scanf("%d%d", &x, &y);
  95. if (y != m) {
  96. ta = s[x].nxt(y);
  97. tb = back.nxt(x);
  98. s[x].insert(tb);
  99. back.insert(ta);
  100. } else {
  101. ta = back.nxt(x);
  102. back.insert(ta);
  103. }
  104. printf("%lld\n", ta);
  105. }
  106. return 0;
  107. }

  

C++ Code:(UOJ)

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #define maxn 5000010
  4. using namespace std;
  5. struct node{
  6. int l, r;
  7. long long head;
  8. void operator -= (long long a) {l -= a; r -= a;}
  9. } val[maxn];
  10. int n, m, q;
  11. int lc[maxn], rc[maxn], num[maxn], sz[maxn], tg[maxn], idx;
  12. struct treap {
  13. int root, len;
  14. int ta, tb, tmp;
  15. int nw(node x) {
  16. val[++idx] = x;
  17. sz[idx] = 1;
  18. num[idx] = rand();
  19. lc[idx] = rc[idx] = 0;
  20. return idx;
  21. }
  22. void update(int p) {sz[p] = sz[lc[p]] + sz[rc[p]] + 1;}
  23. void pushdown(int p) {
  24. int tmp6 = tg[p]; tg[p] = 0;
  25. val[lc[p]] -= tmp6;
  26. val[rc[p]] -= tmp6;
  27. tg[lc[p]] += tmp6;
  28. tg[rc[p]] += tmp6;
  29. }
  30. void splitl(int rt, int k, int &x, int &y) {
  31. if (!rt) x = y = 0;
  32. else {
  33. if (val[rt].l <= k) splitl(rc[rt], k, rc[rt], y), x = rt;
  34. else splitl(lc[rt], k, x, lc[rt]), y = rt;
  35. update(rt);
  36. }
  37. }
  38. void splitr(int rt, int k, int &x, int &y) {
  39. if (!rt) x = y = 0;
  40. else {
  41. pushdown(rt);
  42. if (val[rt].r <= k) splitr(rc[rt], k, rc[rt], y), x = rt;
  43. else splitr(lc[rt], k, x, lc[rt]), y = rt;
  44. update(rt);
  45. }
  46. }
  47. int merge(int x, int y) {
  48. if (!x || !y) return x | y;
  49. if (num[x] > num[y]) {
  50. pushdown(x);
  51. rc[x] = merge(rc[x], y);
  52. update(x);
  53. return x;
  54. } else {
  55. pushdown(y);
  56. lc[y] = merge(x, lc[y]);
  57. update(y);
  58. return (y);
  59. }
  60. }
  61. void build(node p) {
  62. root = nw(p);
  63. }
  64. void insert(long long p, int k = -1){
  65. if (k == -1) k = len;
  66. if (!root) root = nw((node) {k, k, p});
  67. else root = merge(root, nw((node) {k, k, p}));
  68. }
  69. long long nxt(int k) {
  70. splitr(root, k - 1, ta, tmp);
  71. splitl(tmp, k, tmp, tb);
  72. int a = nw((node) {val[tmp].l, k - 1, val[tmp].head}),
  73. b = nw((node) {k + 1, val[tmp].r, val[tmp].head + k + 1 - val[tmp].l});
  74. tb = merge(b, tb);
  75. tg[tb]++;
  76. val[tb] -= 1;
  77. root = merge(merge(ta, a), tb);
  78. return k - val[tmp].l + val[tmp].head;
  79. }
  80. } s[300010], back;
  81. int main() {
  82. srand(20040826);
  83. scanf("%d%d%d", &n, &m, &q);
  84. back.len = n;
  85. for (long long i = 1; i <= n; i++) back.insert(i * m, i);
  86. for (long long i = 1; i <= n; i++) {
  87. s[i].len = m - 1;
  88. s[i].build((node){1, m - 1, (i - 1) * m + 1});
  89. }
  90. int x, y;
  91. long long ta, tb;
  92. while (q--) {
  93. scanf("%d%d", &x, &y);
  94. if (y != m) {
  95. ta = s[x].nxt(y);
  96. tb = back.nxt(x);
  97. s[x].insert(tb);
  98. back.insert(ta);
  99. } else {
  100. ta = back.nxt(x);
  101. back.insert(ta);
  102. }
  103. printf("%lld\n", ta);
  104. }
  105. return 0;
  106. }

  

[NOIP2017 TG D2T3]列队的更多相关文章

  1. 【NOIP题解】NOIP2017 TG D2T3 列队

    列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...

  2. [NOIp2017提高组]列队

    [NOIp2017提高组]列队 题目大意 一个\(n\times m(n,m\le3\times10^5)\)的方阵,每个格子里的人都有一个编号.初始时第\(i\)行第\(j\)列的编号为\((i-1 ...

  3. 【学术篇】NOIP2017 d2t3 列队phalanx splay做法

    我可去他的吧.... ==============先胡扯些什么的分割线================== 一道NOIP题我调了一晚上...(其实是因为昨晚没有找到调试的好方法来的说...) 曾经我以 ...

  4. NOIP2017 D2T3列队

    这题我改了三天,考场上部分分暴力拿了50,考完试发现与正解很接近只是没写出来. 对于每一行和最后一列建n+1颗线段树,维护前缀和. 复杂度qlogn 假如你移动一个坐标为(x,y)的人,你要将第x行线 ...

  5. noip2017 TG 游记

    嗨小朋友们大家好,还记得我是谁吗?我就是为GG代言的蒟蒻--xzz 今天呐我特别的要向HN的dalao们ZJ的巨佬们还有全国的神犇们问声好 为什么呢因为我们在2017年11月份来到了吔屎的长沙理工大学 ...

  6. NOIP2017 Day2 T3 列队(treap)

    可以直接用treap上大模拟...n+1个treap维护n行的前m-1个点和最后一列. 需要支持删除一个点或者一段区间,而空间并不支持存下所有的点的时候,可以用一个点代替一个区间,记录区间首项的值和区 ...

  7. [NOIP2015 TG D2T3]运输计划

    题目大意: 给你一棵n个节点的树,有边权,有多个任务,每个要求从ui号节点到 vi号节点去.m 个计划, 这 m 个计划会同时开始.当这 m 个任务都完成时,工作完成. 现在可以把任意一个边的边权变为 ...

  8. [NOIP2016 TG D2T3]愤怒的小鸟

    题目大意:有一架弹弓位于(0,0)处,每次可以用它向第一象限发射一只小鸟,飞行轨迹均为形如y=ax2+bxy=ax+bx2 y=ax2+bx的曲线,且必须满足a<0(即是下开口的) 平面的第一象 ...

  9. [NOIP2017 TG D2T2]宝藏(模拟退火)

    题目大意:$NOIPD2T2$宝藏 题解:正常做法:状压DP .这次模拟退火,随机一个排列,$O(n^2)$贪心按排列的顺序加入生成树 卡点:没开$long\;long$,接受较劣解时判断打错,没判$ ...

随机推荐

  1. Mysql错误积累001-load data导入文件数据出现1290错误

    错误出现情景 在cmd中使用mysql命令,学生信息表添加数据.使用load data方式简单批量导入数据. 准备好文本数据: xueshengxinxi.txt 文件  数据之间以tab键进行分割 ...

  2. hive的load命令

    Hive Load语句不会在加载数据的时候做任何转换工作,而是纯粹的把数据文件复制/移动到Hive表对应的地址. 语法 LOAD DATA [LOCAL] INPATH 'filepath' [OVE ...

  3. jenkins+maven+docker集成java发布(一)自动发布

    JAVA项目持续集成发布 标签(空格分隔): java jenkins 微服务中持续集成自动发布是很重要的一个环节,将不同的模块应用自动部署到一台或者N台服务器中如果采用人工部署的方式不太现实 git ...

  4. Python学习:2.Python集成学习环境(IDE)Pycharm的安装配置以及激活方

    一.下载Pycharm Pycharm作为Python现在最流行的集成开发环境,我们今后的Python的学习也就使用Pycharm进行,那今天我们就讲一下Pycharm的安装配置以及激活 1.我们首先 ...

  5. C# 实现程序开机自启动

    最近在做一个自动备份文件的小工具,需要用到开机自启动 下面是代码 private void checkBox8_CheckedChanged(object sender, EventArgs e) { ...

  6. 001---Linux系统的启动过程

    Linux系统的启动过程 按下电源 开机自检(BIOS):检查cpu.内存.硬盘是否有问题,找到启动盘. MBR引导(master boot record):主引导记录,读取存储设备的512bytes ...

  7. P1396 营救(最小瓶颈路)

    题目描述 “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门…… 妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小 ...

  8. ABAP CDS ON HANA-(4)ヘッダー行編集

    Explicit Name List use in CDS We create a simple  CDS View like below. @AbapCatalog.sqlViewName: ‘ZS ...

  9. Plsql developer 怎么在打开时登陆配置oracel client?

    配置前 logon 这块是空白的,该怎么配置呢? 看下面 --> 安装完plsql 后 需要安装 oracle client, 这里不再赘述,请自行百度.下面将贴出如何使用 oracle cli ...

  10. nginx location优先级

    目录 1. 配置语法 2. 配置实例 3. 总结: 网上查了下location的优先级规则,但是很多资料都说的模棱两可,自己动手实地配置了下,下面总结如下. 1. 配置语法 1> 精确匹配 lo ...