我可去他的吧....

先胡扯些什么的分割线====

一道NOIP题我调了一晚上...(其实是因为昨晚没有找到调试的好方法来的说...)

曾经我以为我写完了然后全WA 0分 发现

2 1 2
1 1
1 1

这组数据能把我卡掉(我都不知道怎么过样例的)...

然后就开始调就精神崩溃就放弃治疗就划水就过去了一下午和一晚上...

今天我立(砾)志要完成这道题.

上luogu打卡 两个号(不要问我为啥两个号)分别:





然后说我调不出WA的题我就很绝望啊 因为昨晚还有个烂摊子没收拾呢

(其实昨晚最后精神崩溃放弃治疗转而划水划得太high了结果就没调出来)

看了看d2t3的基本思路 画了画图觉得可做 正好最近重拾了splay可以用splay写一写

(不是很清楚线段树啊树状数组啊怎么做的是吧OvO做法似乎没有这么显然 动态加点线段树我也没写过...)

不过昨晚把模拟写好了 小数据调起来还是不算很费劲 但昨天认死了要调指针是导致精神崩溃的根本原因...

都动用了VS不过显然还是不如输出调试直观2333

明明像今天一样小数据对拍+模拟+输出调试+面向数据差错调个1h这不就AC了么→_→

啧啧啧, 其实还是感谢luogu的反向打卡加成...

=胡扯点什么结束的分割线=====

然后我们来说一下做法...

30分?

想怎么做怎么做... 考场上不少人都水了30分暴力吧... (这就是我的模拟方法啊OvO)

50分?

询问少据说专门处理询问的行列就完了...但是考场上我sb地认为时间能跑过却忘了数组开不开...GG....

80分?

考场上想到了\(O(nlog^2_2n)\)的做法...只有一行一列不是...就是把询问数变为n*m+q(询问个数)

然后每次查个k大的映射值就好了... 但是考场上不会写splay... 于是就二分+树状数组水... 不过3e5好像要跑98M多... 然后果不其然被CCF老爷机卡掉了OvO 于是30+10滚粗...

100分?

其实我的80分思路基本是对的(其实差好多不是)OvO

我们先来看一下每次的变化...(我们查询\((1,1)\))

\[\begin{bmatrix}
1 & 2 & 3 & 4 & 5\\ 6 & 7 & 8 & 9 & 10\\ 11 & 12 & 13 & 14 & 15\\16 & 17 & 18 & 19 & 20
\end{bmatrix}
=>
\begin{bmatrix}
2 & 3 & 4 & 5\\6 & 7 & 8 & 9 & 10\\11 & 12 & 13 & 14 & 15\\16 & 17 & 18 & 19 & 20
\end{bmatrix}
=>
\begin{bmatrix}
2 & 3 & 4 & 5 & 10\\6 & 7 & 8 & 9 & 15\\11 & 12 & 13 & 14 & 20\\16 & 17 & 18 & 19 & 1
\end{bmatrix}
\]

我们发现第m列不管你改哪都会动 这就非常麻烦 我们把它单独提出来用一颗splay处理... 然后每行开splay维护\([1..m-1]\)

这样时间复杂度(似乎)就够了 不过显然空间开不开...(尤其是开池子的人)

我们不妨就用点来表示区间 每个点存储\([l,r]\)这个连续区间的信息...

但是操作完不就不连续了么?

所以这就是要每行开一棵splay的原因...

当我们查询到一个点\(p\)时, 我们拆成\([l,p-1],[p,p],[p+1,r]\)三个点...放到splay上转就好了...

因为询问只有\(3*10^5\)个 所以我们最多也就开120W个点嘛 还是能开开的...

这样我们每次查询\((x,y)\)要进行的操作就是:

  • 若y%m==0 (即查询最后一列的点), 直接在第m+1棵(或第0棵你随意)splay上查第x大, 然后把这个点输出、删除再插入...
  • 否则 在第x棵树上查询第y大所在的区间p 把这个区间删除...
  • 将p拆成\([p_l,y-1] [y,y] [y+1,p_r]\) (当然这些区间中要是有\(l>r\)的当然就不要了)
  • 在第m+1棵树上查询第x大 这个点叫\([x,x]\)好了, 把这个点删掉...
  • 把\([x,x]\)插到第x棵树的最后, 把\([y,y]\)插到第m棵树的最后, 把\([p_l,y-1]\)和\([y+1,p_r]\)插到原来p的位置就行了...
  • 最后输出y就行了...

然后就是一些细节问题了OvO

比如时间的先后问题 写残了好多遍, 最后发现n*m+q就没有问题了...

比如查询的时候要先算w再splay 不然会算错(可能是我太sb了)

比如\((3*10^5)^2\)要开long long...

比如splay基本操作不要写挂.. 就这样吧...

代码:

#include <cstdio>
typedef long long LL; LL n,m,q;
inline LL gn(LL a=0,char c=0){
for(;c<48||c>57;c=getchar());for(;c>47&&c<58;c=getchar())a=a*10+c-48;return a;
} struct SPLAY{
struct node{
LL l,r,sz,cnt,ti;
node *ch[2],*fa;
void update(){sz=ch[0]->sz+ch[1]->sz+cnt;}
int getwh(){return fa->ch[1]==this;}
void setch(int wh,node *child);
}*rt; void init();
void rotat(node *now);
void splay(node *now,node *tar);
void inser(node *nnow);
node* find(LL k,LL &w);
void delet(node *now);
}sp[300005];
SPLAY::node *null,pool[3000005]; LL tot; void SPLAY::node::setch(int wh,node *child){
ch[wh]=child; if(child!=null) child->fa=this;
update();
} SPLAY::node* NEW(LL l,LL r,LL t){
if(l>r) return null;
SPLAY::node *now=pool+ ++tot; now->ti=t;
now->l=l; now->r=r; now->sz=now->cnt=r-l+1;
now->ch[0]=now->ch[1]=now->fa=null;
return now;
} void SPLAY::rotat(node *now){
int wh=now->getwh(); node *fa=now->fa,*fafa=fa->fa;
if(fafa!=null) fafa->ch[fa->getwh()]=now;
fa->setch(wh,now->ch[wh^1]);
now->setch(wh^1,fa);
now->fa=fafa;
} void SPLAY::splay(node *now,node *tar){
for(;now->fa!=tar;rotat(now))
if(now->fa->fa!=tar)
now->getwh()==now->fa->getwh()?rotat(now->fa):rotat(now);
if(tar==null) rt=now;
} void SPLAY::inser(node *nnow){
node *fa=null,*now=rt;
while(now!=null){
fa=now;
if(nnow->ti<now->ti) now=now->ch[0];
else now=now->ch[1];
}
if(fa==now) rt=nnow;
else if(nnow->ti<fa->ti) fa->setch(0,nnow);
else fa->setch(1,nnow);
splay(nnow,null);
} SPLAY::node* SPLAY::find(LL k,LL &w){
node *now=rt; LL ls=0;
while(now!=null){
if(ls+now->ch[0]->sz<k&&ls+now->ch[0]->sz+now->cnt>=k){
w=k-(ls+now->ch[0]->sz)+now->l-1;
splay(now,null);
return now;
}
if(ls+now->ch[0]->sz>=k) now=now->ch[0];
else ls+=now->ch[0]->sz+now->cnt,now=now->ch[1];
}
return null;
} void SPLAY::delet(node *now){
if(now->ch[0]==null&&now->ch[1]==null) rt=null;
else if(now->ch[0]==null) rt=now->ch[1],now->ch[1]->fa=null;
else if(now->ch[1]==null) rt=now->ch[0],now->ch[0]->fa=null;
else{
node *rs=now->ch[0];
while(rs->ch[1]!=null) rs=rs->ch[1];
splay(rs,null);
rs->setch(1,now->ch[1]);
rt=rs; rs->fa=null;
}
} void init(){
null=pool; null->l=null->r=null->sz=null->cnt=0;
null->ch[0]=null->ch[1]=null->fa=null;
for(int i=0;i<=n;++i) sp[i].rt=null;
} LL query(int q,int x,int y){
if(y%m==0){
LL p=0; SPLAY::node *now=sp[0].find(x,p);
p=now->l;
sp[0].delet(now);
sp[0].inser(NEW(p,p,n*m+q));
return p;
}
else{
LL p=0,p2=0;
SPLAY::node *now=sp[x].find(y,p);
// printf("A%d %d %d\n",p,now->l,now->r);
SPLAY::node *now2=sp[0].find(x,p2);
// printf("B%d %d %d\n",p2,now2->l,now2->r);
p2=now2->l;
sp[x].delet(now);
sp[0].delet(now2);
if(p>now->l) sp[x].inser(NEW(now->l,p-1,now->l));
if(p<now->r) sp[x].inser(NEW(p+1,now->r,p+1));
sp[x].inser(NEW(p2,p2,n*m+q));
sp[0].inser(NEW(p,p,n*m+q));
return p;
}
return 0;
} void debugtree(SPLAY::node *now){
if(now->ch[0]!=null) debugtree(now->ch[0]);
printf("%d %d\n",now->l,now->r);
if(now->ch[1]!=null) debugtree(now->ch[1]);
} void solve(){
for(LL i=1;i<=n;++i)
sp[i].inser(NEW((i-1)*m+1,i*m-1,(i-1)*m+1));
for(LL i=1;i<=n;++i)
sp[0].inser(NEW(i*m,i*m,i*m));
for(LL i=1,x,y;i<=q;++i){
x=gn(),y=gn();// query(x,y);
printf("%lld\n",query(i,x,y));
// puts("```");
// for(int i=1;i<=n;++i)
// debugtree(sp[i].rt),putchar(10);
// debugtree(sp[0].rt);
// puts("```");
}
}
int main(){
// freopen("phalanx.in","r",stdin); freopen("phalanx.out","w",stdout);
n=gn(),m=gn(),q=gn(); init(); solve();
}

其实最后一个点在luogu上就跑了1800+ms 平衡树的常数是真的大(而且我可能写的丑什么的常数就更大了)

所以其实打卡说的没错 放到NOIP老爷机上估计就变成TLE了...

然而我实在懒得去卡常数了 就这样吧...

【学术篇】NOIP2017 d2t3 列队phalanx splay做法的更多相关文章

  1. 【NOIP2017】列队(Splay)

    [NOIP2017]列队(Splay) 题面 洛谷 题解 其实好简单啊... 对于每一行维护一棵\(Splay\) 对于最后一列维护一棵\(Splay\) \(Splay\)上一个节点表示一段区间 每 ...

  2. NOIP2017 D2T3列队

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

  3. [luogu P3960] [noip2017 d2t3] 队列

    [luogu P3960] [noip2017 d2t3] 队列 题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Syl ...

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

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

  5. Luogu3960 NOIP2017列队(splay/线段树)

    令splay中的一个点表示一段区间,需要使用其中某个点时将区间分裂即可,剩下的都是splay的基本操作了.写的非常丑陋,注意细节.感觉考场上肯定只能靠部分分苟活了.想起来去年因为各种莫名其妙的原因50 ...

  6. [NOIP2017]列队 (Splay)

    题目链接 NOIP2017真的是不按常理出牌: 1.数学题不在Day2T1 2.一道水题一道细节极多的模拟题一道不知道怎么形容的题(小凯的疑惑)(因为我太菜了) 3.3道大火题 当时看到列队这题是毫无 ...

  7. 【NOIP2017】列队 splay

    当年太菜了啊,连$60$分的暴力都没拿满,只打了一个$30$分的. 考虑到这题最多只会询问到$30W$个点,且整个矩阵会去到$30W\times 30W$,显然不能将所有的点存下来. 对于每一行(除最 ...

  8. [NOIP2017 TG D2T3]列队

    题目大意:有一个$n \times m$的方阵,第$i$行第$j$列的人的编号是$(i-1) \times m + j$. 现在有$q$个出列操作,每次让一个人出列,然后让这个人所在行向左看齐,再让最 ...

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

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

随机推荐

  1. Django框架(十二)—— 补充:inclusion_tag、defer、only、choice、事务、创建多对多的第三张表

    目录 补充:inclusion_tag.defer.only.choice.事务.创建多对多的第三张表 一.inclusion_tag 1.作用 2.使用 二.defer与only 1.定义 2.使用 ...

  2. js关于if()else{}中的判定条件的认识,各种数据类型转换为Boolean类型的转换规则

    博客搬迁,给你带来的不便敬请谅解! http://www.suanliutudousi.com/2017/09/24/js%E5%85%B3%E4%BA%8Eifelse%E4%B8%AD%E7%9A ...

  3. 在vue中获取不到canvas对象? 两种解决办法。

    1. mounted 钩子函数 初次肯定获取到id 2. 如果canvas父级用到了v-if 请改成v-show ,vue Dom节点 重新渲染导致methods 方法获取不到对象.

  4. vue与webpack

    由于最近在vue-cli生成的webpack模板项目的基础上写一个小东西,开发过程中需要改动到build和config里面一些相关的配置,所以刚好趁此机会将所有配置文件看一遍,理一理思路,也便于以后修 ...

  5. D3.js(v3)+react 制作 一个带坐标与比例尺的散点图 (V3版本)

    上一章做了柱形图,https://www.cnblogs.com/littleSpill/p/10835041.html   这一章做散点图.   散点图(Scatter Chart),通常是一横一竖 ...

  6. 【转】谈一谈 Normalize.css

    原文链接: https://www.jianshu.com/p/9d7ff89757fd 笔记: 如何使用?

  7. lambda和DynamoDB连接

    在DynamoDB当作创建一个新表,然后在项目当中创建,把string value的值填写一下. 在IAM创建角色附加 AWSLambdaDynamoDBExecutionRole权限 在lambda ...

  8. c 语言函数分析

    第一个参数为指向线程标识符的指针. 第二个参数用来设置线程属性. 第三个参数是线程运行函数的起始地址. 最后一个参数是运行函数的参数. result = pthread_create(&tid ...

  9. leetcode-158周赛-5222-分割字符串

    题目描述: 自己的提交: class Solution: def balancedStringSplit(self, s: str) -> int: if not s:return 0 res ...

  10. Kafka Streams详细

    概述 1 Kafka Streams Kafka Streams.Apache Kafka开源项目的一个组成部分.是一个功能强大,易于使用的库.用于在Kafka上构建高可分布式.拓展性,容错的应用程序 ...