noip出这个题简直丧心病狂,省选都没考过这么恶心的splay

这个题思路不是很难找,要点只有两个:特殊数据和动态结构

首先纵向发生变化的一定是最右边的一列,所以它是特殊的

然后询问只有1e5 ,而矩阵是1e5*1e5的,所以询问少,是特殊的

所有的操作等价于从一行中选择一个,插入到最后一列的队尾,从最后一列中选择一个,插入到一列的队尾

一开始想用离线线段树做,存sz,合并不会被询问的点团,但这样不被询问的点团也有可能被询问,所以还是需要动态维护

所以就需要动态的结构,用splay维护最右边一列、每一行

利用splay的sz和起始值大小来压缩区间,需要时分裂、删除和插入

非常难写,写了一天

码:

#include<iostream>
#include<cstdio>
using namespace std;
#define N 3000005
int ch[N][2],op,fu[N],rt[N],tot,q;
long long sz[N],szh[N],v[N],c,a,b,i,x,y,n,m;
void up(int o)
{szh[o]=szh[ch[o][0]]+szh[ch[o][1]]+sz[o];
}
void set(int a,int wh,int child)
{ch[a][wh]=child;fu[child]=a;up(a);
}
int getwh(int o)
{return ch[fu[o]][0]==o?0:1;
}
void rotate(int o)
{int fa=fu[o],ye=fu[fa];int wh=getwh(o);set(fa,wh,ch[o][wh^1]);set(o,wh^1,fa);fu[o]=ye;if(ye!=0){ch[ye][ch[ye][0]==fa?0:1]=o;       }
}
void splay(int hang,int o,int tar)
{for(;fu[o]!=tar;rotate(o))if(fu[fu[o]]!=tar) getwh(o)==getwh(fu[o])?rotate(fu[o]):rotate(o);if(tar==0)rt[hang]=o;
}
int xin()
{
v[++tot]=a;
sz[tot]=szh[tot]=b;
return tot;
}
void del(int hang,int o)
{splay(hang,o,0);if(ch[o][0]==0){fu[ch[o][1]]=0;rt[hang]=ch[o][1];  }else if(ch[o][1]==0){fu[ch[o][0]]=0;rt[hang]=ch[o][0];}else{int p=ch[o][0];while(ch[p][1])p=ch[p][1];ch[p][1]=ch[o][1];fu[ch[o][1]]=p;fu[ch[o][0]]=0;rt[hang]=ch[o][0];splay(hang,p,0);}
}
void zhao(int qu,int bu,int mb)
{int o=rt[qu],last=0;while(o){last=o;if(szh[ch[o][0]]+1<=mb&&szh[ch[o][0]]+sz[o]>=mb){mb-=szh[ch[o][0]];c=v[o]+mb-1; splay(qu,o,0); if(op==0)//取出行里,补到列里 {if(sz[o]==1)//直接删 {del(qu,o);          }else           if(mb==1)//只裂出右边{a=c+1; b=sz[o]-1;int rr=xin();if(ch[o][1]==0){set(o,1,rr);}else{int p=ch[o][1];while(ch[p][0])p=ch[p][0];set(p,0,rr);}splay(qu,rr,0);del(qu,o);              }else if(mb==sz[o])//只裂出左边 {a=v[o]; b=sz[o]-1;int ll=xin();if(ch[o][0]==0){set(o,0,ll);}else{int p=ch[o][0];while(ch[p][1])p=ch[p][1];set(p,1,ll);}splay(qu,ll,0);del(qu,o);       }else{a=c+1; b=sz[o]-mb;int rr=xin();if(ch[o][1]==0){set(o,1,rr);}else{int p=ch[o][1];while(ch[p][0])p=ch[p][0];set(p,0,rr);}splay(qu,rr,0);splay(qu,o,0);a=v[o]; b=mb-1;int ll=xin();if(ch[o][0]==0){set(o,0,ll);}else{int p=ch[o][0];while(ch[p][1])p=ch[p][1];set(p,1,ll);}splay(qu,ll,0);del(qu,o);                  }o=rt[bu];while(ch[o][1])o=ch[o][1];a=c,b=1;int rr=xin();          if(o)set(o,1,rr);else rt[bu]=rr;splay(bu,rr,0);}else  if(op==1)//取出列里补到行里 {c=v[o];del(qu,o);o=rt[bu];while(ch[o][1])o=ch[o][1];a=c,b=1;int rr=xin();           if(o)set(o,1,rr);else rt[bu]=rr;splay(bu,rr,0);    }else//取出列里补到列里 {c=v[o];del(qu,o);o=rt[bu];while(ch[o][1])o=ch[o][1];a=c,b=1;int rr=xin();            if(o)set(o,1,rr);else rt[bu]=rr;splay(bu,rr,0);        }return;    }if(szh[ch[o][0]]>=mb)o=ch[o][0];else mb-=sz[o]+szh[ch[o][0]],o=ch[o][1];}
}
int jian(int l,int r)
{if(l>r)return 0;int mid=(l+r)>>1;sz[++tot]=1;szh[tot]=1;v[tot]=m*mid;int lin=tot;ch[lin][0]=jian(l,mid-1);
if(ch[lin][0])  fu[ch[lin][0]]=lin;    ch[lin][1]=jian(mid+1,r);
if(ch[lin][1])  fu[ch[lin][1]]=lin;    szh[lin]+=szh[ch[lin][0]]+szh[ch[lin][1]];
return lin;
}
int main()
{scanf("%lld%lld%d",&n,&m,&q);for(i=1;i<=n;i++){a=(i-1)*m+1;b=m-1;rt[i]=xin();}rt[0]=tot+1;jian(1,n);for(i=1;i<=q;i++){scanf("%d%d",&x,&y);if(y==m){op=2;            zhao(0,0,x);printf("%lld\n",c);}else{op=0;zhao(x,0,y);   printf("%lld\n",c);op=1;zhao(0,x,x);}        }
}

[noip2017]列队 splay相关推荐

  1. NOIP2017 列队

    https://www.luogu.org/problemnew/show/P3960 p<=500 50分 模拟 每个人的出队只会影响当前行和最后一列 p<=500,有用的行只有500行 ...

  2. NOIP2017 列队——动态开点线段树

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

  3. 【学习笔记】Splay

    普通平衡树 模板题链接 1.引入 一种二叉树,这棵树满足任意一个节点,它的左儿子的权值<自己的权值<右儿子的权值 这种树叫做二叉查找树,这个概念应该在初赛中见过了吧 Splay就是利用这个 ...

  4. OI每周刷题记录——lrllrl

    看这标题就知道我是模仿的hzwer大佬,远程%%% 大佬的OI经历让蒟蒻我深受感触,为了晚一些AFO本蒟蒻也得加油了 从高二上期第一周开始计数,每个星期天更一次,一直更到我AFO 如果这是我此生最后一 ...

  5. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  6. 【NOIP2017提高组】列队

    题目背景 NOIP2017提高组 DAY2 T3 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵.Sylvia 所在的方阵中 ...

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

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

  8. 【洛谷】3960:列队【Splay】

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

  9. 洛谷P3960 列队(Splay)

    传送门 感觉自己好久不打数据结构已经完全不会了orz-- 据说正解树状数组?然而并不会 首先考虑一下每一次操作,就是把一个人从这一行中取出并放到行的最后,再从最后一列取出放到列的最后 那么这两种操作其 ...

最新文章

  1. 代码质量第4层——健壮的代码!
  2. 二分查找对应的二叉树的成功和失败ASL
  3. 我的第一个ASP类(显示止一篇下一篇文章)
  4. 美利好车的微服务实践
  5. 以太坊源码学习 -- EVM
  6. 中石油训练赛 - 姓氏(思维+水题)
  7. C++ 常用查找算法
  8. python modbus控制plc_python Modbus基础
  9. 一个问题引发的连环血案
  10. OSDI 2022 Roller 论文解读
  11. 蓝牙小钢炮 - Bose 博士 Revolve 蓝牙音箱使用感受
  12. 读书笔记—《雷达信号处理基础》第一章 雷达系统与信号处理概述(2)
  13. asp与php的区别
  14. Ubuntu 搜狗输入法 关闭简繁切换快捷键
  15. 记一次机房断电办公室网络瘫痪的恢复经过
  16. 骏飞H5幸运刮刮乐源码多级分佣+upupw直接架设+H5微信登陆公众号接入 管理员
  17. 服务器硬件规格常用查看命令——CPU相关命令
  18. 【UTR #1】ydc的大树
  19. 蓝牙耳机无法打开计算机,电脑搜不到蓝牙耳机怎么回事_电脑搜不到蓝牙耳机的处理方法【图文】...
  20. python 画k线_使用matplotlib绘制k线图

热门文章

  1. 魅族mx四核即将使用android,魅族MX四核智能手机发布
  2. Spark内核解析1
  3. memcache入门
  4. Kotlin学习笔记 第二章 类与对象 第三节接口 第四节 函数式接口
  5. ora-28500 ora-02063 mysql_oracle dblink mysql 报错ORA-28500
  6. virtualbox虚拟机安装Ubuntu异常处理:FATAL: NO bootable medium found! System halted
  7. Java中遭遇NaN
  8. 北师大计算机组成原理答案,计算机组成原理(白中英)本科生试题库整理附答案[共21页].doc...
  9. p=(1 r) 2c语言编程,菜鸟编程~!1.2
  10. 数据分析流程和特征工程