~~~题面~~~

题解:

  之前写的splay,,,然而一直没调出来,我感觉是某个细节想错了,,然而已经重构4次代码不想再写splay了。于是今天尝试了线段树的解法。

  首先因为每次出列之后的变化都是将当前行左移,然后将最后一列上移,所以最后一列不适合和其他的行放在一起处理。

  因此对于每行的前m - 1位开一棵线段树,对于最后一列开一棵线段树。

  但是因为空间开销过大无法承受,因此考虑动态开点。一开始每棵线段树内只有一个节点,这个节点代表了当前行1 ~ m - 1的所有节点。

  如果我们要从中删除一个节点,就跟普通线段树类似的向下遍历找到单点,然后修改权值为0,并且同步修改这条链上的节点数总和。跟普通线段树不同的是,动态开点需要在函数的最开头判断这个节点是否存在,如果不存在,就建出这个节点,并给这个节点加上一些基本的信息,然后继续向下遍历。

  如果我们要添加一个节点到树中,那么我们就直接加在这棵树所有已经存在的叶子节点的后面那个叶子节点处即可。即下图。(虚线表示省略的节点)

同时维护所有线段树即可,注意细节。

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 301000
#define ac 8000000
#define LL long long
#define D printf("line in %d\n", __LINE__); int n, m, q, w, cnt, now;
int root[AC], tree[ac], ls[ac], rs[ac], pos[ac];
LL id[ac], go;//id[ac]要开ac啊,,,,
//对于
inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline int cal(int l, int r)
{
if(now <= n)
{
if(r <= m - ) return r - l + ;
else if(l <= m - ) return (m - ) - l + ;
else return ;
}
else
{
if(r <= n) return r - l + ;
else if(l <= n) return n - l + ;
else return ;
}
} void kth(int &x, int l, int r)//当前节点,当前区间
{
if(!x) x = ++ cnt, tree[x] = cal(l, r);//第一次开出来自然是满的
if(l == r)
{
tree[x] = ;
if(!id[x]) go = (now <= n) ? (LL)(now - ) * (LL)m + l : (LL)m * (LL)l;//如果这个点没有被赋过值,那么就应该是原来的编号
else go = id[x]; //编号爆ll,,,
return ;
}
else
{
-- tree[x];//删除一个节点
int mid = (l + r) >> ;
int tmp = ls[x] ? tree[ls[x]] : cal(l, mid);//获取左边的节点个数
if(w <= tmp) kth(ls[x], l, mid);
else w -= tmp, kth(rs[x], mid + , r);
}
} void ins(int &x, int l, int r)
{
if(!x) x = ++ cnt, tree[x] = cal(l, r);
if(l == r) {tree[x] = , id[x] = go; return ;}
int mid = (l + r) >> ;
++ tree[x];//加入一个节点
if(w <= mid) ins(ls[x], l, mid);//因为已经钦定了位置
else ins(rs[x], mid + , r);//不然去右边
} void pre()
{
n = read(), m = read(), q = read();
for(R i = ; i <= n; i ++) root[i] = ++cnt, tree[cnt] = m - ;
root[n + ] = ++cnt, tree[cnt] = n;//给最后一列单独开一个
} void work()
{
int a, b;LL tmp;
for(R i = ; i <= q; i ++)
{
a = read(), b = read();
if(b < m)
{
now = a, w = b;
kth(root[now], , m + q);//对于维护行的线段树,边界应该是m + q吧
w = a, now = n + , tmp = go;//记录出来的人
printf("%lld\n", tmp);
kth(root[now], , n + q);//从最后一列中取人,
now = a, ++ pos[now], w = m - + pos[now];
ins(root[now], , m + q);
now = n + , ++ pos[now], w = n + pos[now], go = tmp;//把出来的人放在最后一列的最后一个
ins(root[now], , n + q);
}
else
{
now = n + , w = a;
kth(root[now], , n + q);
printf("%lld\n", go);
++ pos[now], w = n + pos[now];//直接算出来应该放在哪个位置
ins(root[now], , n + q);
}
}
} int main()
{
// freopen("in.in", "r", stdin);
pre();
work();
// fclose(stdin);
return ;
}

[NOIP2017]列队 线段树的更多相关文章

  1. [NOIP2017]列队(线段树/裂点splay)

    考虑n=1的做法,就是支持: 1.在线删一个数 2.在结尾加一个数 3.查询序列的第y个数 用线段树记录区间内被删元素的个数,可以通过线段树上二分快速得解,对于新增的数,用vector记录即可. 对于 ...

  2. 【noip2017】【Luogu3960】列队 线段树

    题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n \times mn×m 名学生,方阵的 ...

  3. Luogu P3960 列队 线段树

    题面 线段树入门题. 我们考虑线段树来维护这个矩阵. 首先我们先定n+1棵线段树前n棵维护每行前m-1个同学中没有离队过的同学,还有一棵维护第m列中没有离队过的同学.再定n+1棵线段树前n棵线段树维护 ...

  4. 洛谷 P3960 [ NOIP 2017 ] 列队 —— 线段树

    题目:https://www.luogu.org/problemnew/show/P3960 NOIP 题,不用很复杂的数据结构...但又参考了许多: 要求支持维护删除第 k 个和在末尾插入的数据结构 ...

  5. [NOIP2017]列队(树状数组)

    定义第i行为所有的点(i,j),0<j<m 可以发现,每一行是相对独立的,每一次操作只会影响到当前行和最后一列 考虑每一行和最后一列各开一个树状数组,但这样显然会爆空间 实际上,对于没有离 ...

  6. NOIP2017 列队 题解报告【56行线段树】

    题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数 ...

  7. NOIP2017提高组Day2T3 列队 洛谷P3960 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/9265380.html 题目传送门 - 洛谷P3960 题目传送门 - LOJ#2319 题目传送门 - Vij ...

  8. 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay

    正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...

  9. 2018.11.01 loj#2319. 「NOIP2017」列队(线段树)

    传送门 唉突然回忆起去年去noipnoipnoip提高组试水然后省二滚粗的悲惨经历... 往事不堪回首. 所以说考场上真的有debuffdebuffdebuff啊!!!虽然当时我也不会权值线段树 这道 ...

随机推荐

  1. JavaSE 第二次学习随笔(关于内存的小题)

    class HelloA { public HelloA() { System.out.println("HelloA"); } { System.out.println(&quo ...

  2. Hadoop(4)-Hadoop集群环境搭建

    准备工作 开启全部三台虚拟机,确保hadoop100的机器已经配置完成 分发脚本 操作hadoop100 新建一个xsync的脚本文件,将下面的脚本复制进去 vim xsync #这个脚本使用的是rs ...

  3. Python的scrapy之爬取boss直聘网站

    在我们的项目中,单单分析一个51job网站的工作职位可能爬取结果不太理想,所以我又爬取了boss直聘网的工作,不过boss直聘的网站一次只能展示300个职位,所以我们一次也只能爬取300个职位. jo ...

  4. powerpoint教程资料,PPT的

    Powerpoint,是微软公司设计的演示文稿软件,利用Powerpoint不仅可以创建演示文稿,还可以在互联网上召开面对面会议.远程会议或在网上给观众展示演示文稿,掌握利用PowerPoint是一项 ...

  5. 001---Python简介

    编程语言: 机器语言 最底层,更容易被计算机识别,执行速度最快 复杂,开发效率低 汇编语言 比较底层,执行速度较快 同样复杂 高级语言 编译型语言:先编译,后执行.生成独立的可执行文件.是计算机可以理 ...

  6. Kubernetes-运维指南

    Node隔离与恢复 cat unschedule_node.yaml apiVersion: kind: Node metadata: name: k8s-node-1 labels: kuberne ...

  7. BZOJ:2038: [2009国家集训队]小Z的袜子(hose)(莫队算法模板)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 解题心得: 第一次接触莫队算法,很神奇,很巧妙.莫队算法主要就是用来解决多次询问时 ...

  8. 分布式redis一些小结

    本文围绕以下几点进行阐述: 为什么使用 Redis 使用 Redis 有什么缺点 单线程的 Redis 为什么这么快 Redis 的数据类型,以及每种数据类型的使用场景 Redis 的过期策略以及内存 ...

  9. 使用sqoop将mysql中表导入hive中报错

    [hdfs@node1 root]$ sqoop import --connect jdbc:mysql://node2:3306/cm?charset-utf8 --username root -- ...

  10. table调整td宽度整理-完美解决--费元星前端

    个人整理例子,留下做个备份 最终重要的几句话 0.日期格式 format="ognl:dateFormat" <td align="center"> ...