[luoguP3960] 列队(动态开点线段树)
传送门
有splay的做法,有树状数组的做法。。。
最好理解的还是线段树的做法。
一开始我是这样想的,如果移动某一个人,只有当前行和最后一列会受到影响,感觉就像是个线段树,树状数组什么的。
然而接下来就想歪了,把一个人移到后面,等于把后面的整体往前移一格,gg
正确思路是权值线段树,如果一个数被移走,相当于这个数的个数1,然后把它变成了m+1,放到后面。
移动第x行第y个人其实就是求第x行的第y大。
这样,每一行和最后一列建一棵线段树,然而超空间。
所以需要动态开点,因为总共只移动3*10^5次,也就是开nlongn的点。
据说逆向思维可以骗50分,这都没想到。。。
最后附上丑陋的,调了一晚上的,连我自己都看不懂的代码——
#include <cstdio>#include <cstring>#include <iostream>#define N 600001#define LL long longusing namespace std;int n, m, q, M, cnt;int size[N], sum[N * 10], ls[N * 10], rs[N * 10], root[N];LL val[N * 10];inline int read()inline LL del(int &now, int l, int r, int x, int f, int h)int mid = (l + r) >> 1;if(mid l + 1 + sum[ls[now]] >= x) return del(ls[now], l, mid, x, f, h);else return del(rs[now], mid + 1, r, x (mid l + 1 + sum[ls[now]]), f, h); }inline void insert(int &now, int l, int r, int x, LL d)int mid = (l + r) >> 1;if(x <= mid) insert(ls[now], l, mid, x, d);else insert(rs[now], mid + 1, r, x, d);}int main()++size[0];insert(root[0], 1, M, size[0], a);}return 0;}
就让这个题作为我回归奥赛的开端,SDOI2018加油!
上一篇:[luoguP1131] [ZJOI2007]时态同步(贪心)
下一篇:[luoguP1129] [ZJOI2007]矩阵游戏(二分图最大匹配)
线段树 树状数组 splay
pla文件怎么看,pla文件用什么打开?
pl1文件怎么看,pl1文件用什么打开?
pl文件怎么看,pl文件用什么打开?
pl0文件怎么看,pl0文件用什么打开?
pkt文件怎么看,pkt文件用什么打开?
pkm文件怎么看,pkm文件用什么打开?
pks文件怎么看,pks文件用什么打开?
pka文件怎么看,pka文件用什么打开?
pkh文件怎么看,pkh文件用什么打开?
pkg文件怎么看,pkg文件用什么打开?