题目传送门
看到 T3 已经就剩
20
20
20 分钟了,一看数据结构……
双手打出 GG……
打了个
30
30
30 暴力,一看这是最后一份代码了,于是纪念了一下:
if(n<=1000)
{
//Some Code
}
puts("Goodbye OI!");
woc这一行没了
30
30
30 分啊直接爆
0
0
0 啊1=没了我怎么想的啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊……
一行送我,OI再见……
正解怎么搞?
通过一些数据都是
x
=
1
x=1
x=1,我们可以知道这些数据是把一个数列中的一个数拿出来放到最后一个,然后这个数之后的其他数依次向前移动一个位置的重复操作。这个操作在 [SCOI2006]动态最值 见到过,可以用线段树维护。
于是
n
n
n 行就是同时有
n
n
n 个这样的数列要完成这样的操作,这样我们解决一个子问题,就可以解决矩阵的问题了。
于是我们维护每一行的前
m
−
1
m-1
m−1 个元素和最后一列,这样就搞出了
n
+
1
n+1
n+1 个序列,还是爆炸……
但是我们发现每一行前
m
−
1
m-1
m−1 个元素和最后一列初始都成等差数列,所以我们可以根据这个性质计算。
可以直接主席树,同时维护一个 vector 记录删除后被扔到最后的那个人的编号。对最后一列操作,如果所处位置没被删除过,就直接计算,否则在 vector 内寻找;如果是对一个普通位置维护,先删除
(
x
,
y
)
(x,y)
(x,y) 位置的人,把它扔到最后一列,然后维护最后一列即可。
时间复杂度:
O
(
T
log
2
n
)
O(T\log_2 n)
O(Tlog2n),空间复杂度:
O
(
n
log
2
n
)
O(n\log_2 n)
O(nlog2n)。
据说在测评的时候线段树被卡了写树状数组才能过……
需要注意主席树的写法……
Code