Rank | Solved | A | B | C | D | E | F | G | H | I | J |
---|---|---|---|---|---|---|---|---|---|---|---|
9/437 | 5/10 | Ø | O | . | O | Ø | O | Ø | O | Ø | O |
O
: 当场通过
Ø
: 赛后通过
.
: 尚未通过
A Eddy Walker
upsolved by viscaria
viscaria’s solution
考虑从点m出来,首先我们一定会先到m+1,m-1,然后就变化成一个随机游走,两个吸收壁的问题。以0与n为吸收壁,点i被n吸收的概率为 i / n i/n i/n(记住记住记住!!!!!)
B Eddy Walker 2
solved by chelly
chelly’s solution
BM算法解决线性递推,时间复杂度是
O
(
k
2
log
n
)
O(k^2 \log n)
O(k2logn)的。
鸣谢dls的模板。
C Go on Strike!
unsolved
D Kth Minimum Clique
solved by chelly&viscaria
chelly’s solution
我们考虑将所有合法团丢进一个priority_queue里,然后不断弹出最小的,第
K
K
K个弹出的就是第
K
K
K小的。
具体来说,对于priority_queue中每个元素,都需要维护一个bitset表示外面的哪些点可以加入这个团。每次扩展的时候枚举bitset里的点扩展即可。但这样最坏情况是
O
(
n
64
n
k
log
(
n
k
)
)
O(\frac{n}{64}nk \log (nk))
O(64nnklog(nk))的。但比赛时候放过了……
事实上,我们的扩展只需要两个策略:将目前下标最大的点换成下标更大的点;新加入一个下标更大的点。这样就是
O
(
n
64
k
log
k
)
O(\frac{n}{64}k \log k)
O(64nklogk)。
E MAZE
upsolved by chelly
chelly’s solution
考虑dp,设
d
p
(
i
,
j
)
dp(i,j)
dp(i,j)表示走到
(
i
,
j
)
(i,j)
(i,j)的方案数。
d
p
(
i
,
j
)
=
∑
k
=
l
r
d
p
(
i
−
1
,
k
)
dp(i,j)=\sum_{k=l}^r dp(i-1,k)
dp(i,j)=∑k=lrdp(i−1,k),其中
g
(
i
,
l
)
=
g
(
i
,
l
+
1
)
=
.
.
.
=
g
(
i
,
r
)
=
0
g(i,l)=g(i,l+1)= ...=g(i,r)=0
g(i,l)=g(i,l+1)=...=g(i,r)=0
于是转移的dp可以表示成两行之间的矩阵乘法,对于修改我们就线段树维护矩阵乘法即可。
F Partition problem
solved by chelly&viscaria
chelly’s solution
一共有 ( 28 14 ) \binom{28}{14} (1428)种合法状态,对于每种合法状态想办法快速统计其价值即可。可以将 2 N 2N 2N分为左半边和右半边,维护一些东西,使得统计价值的过程更加快速即可。
G Polygons
upsolved by viscaria
viscaria’s solution
这道题是平面直线图的裸题,直接套模板就行了,主要值得注意的是建图,把点信息始终存在vector里,使排序的时候不会丢失每个点的定位,可以省去查找点的一个过程。
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(dcmp(Cross(p[i][1]-p[i][0],p[j][1]-p[j][0]))==0)continue;
pp[cnt2++]=GetlineIntersection(p[i][0],p[i][1]-p[i][0],p[j][0],p[j][1]-p[j][0]);
h[i].push_back(seg(Dot(p[i][1]-p[i][0],pp[cnt2-1]-p[i][0]),cnt2-1));
h[j].push_back(seg(Dot(p[j][1]-p[j][0],pp[cnt2-1]-p[j][0]),cnt2-1));
}
sort(h[i].begin(),h[i].end());
}
t.init(cnt2);
for(int i=0;i<cnt2;i++){
t.x[i]=pp[i].x;
t.y[i]=pp[i].y;
}
for(int i=0;i<n;i++){
int num=h[i].size(),u,v;
for(int j=1;j<num;j++){
u=h[i][j-1].p;
v=h[i][j].p;
t.AddEdge(u,v);
}
}
H Second Large Rectangle
solved by chelly&viscaria
chelly’s solution
首先求出一个最大的全1矩阵,然后把其四角分别扣成0,分别再做一次最大全1矩阵,四个数值中的最大值就是次大矩阵。
upsolved by chelly
chelly’s solution
求最大全1矩形还有个不需要用单调栈的做法。可以从上往下依次枚举每行,对于每列维护 l [ j ] , r [ j ] , h [ j ] l[j],r[j],h[j] l[j],r[j],h[j], h [ j ] h[j] h[j]表示第j列向上能到的高度, l [ j ] l[j] l[j]和 r [ j ] r[j] r[j]表示从第 j j j列,以 h [ j ] h[j] h[j]的高度,向左向右能扩展到哪里。比较好写。
I Inside A Rectangle
upsolved by chelly
chelly’s solution
J Subarray
solved by chelly
chelly’s solution
首先考虑如果是1e7个1或者-1,如何在O(n)时间内解决。可以参考一下dreamoon的这个代码。简单来说从左往右扫描,不断维护一个权值数组pre[x],表示目前前面的所有位置中<=x的有多少个。
然后考虑如何处理1e9的情况,在这种情况里,有很多段连续的-1因为个数太多,不会对其前面和后面造成影响,所以可以先维护出可能作为答案的区间。具体来说dp求出每个全1区间右端点向左能得到的最大和,左端点向右能得到的最大和。对于区间[l[i],r[i]]和[l[i+1],r[i+1]],如果从r[i]向左的最大和+从l[i+1]向右的最大和>=中间-1的个数,那么就合并这两个区间。最后会得到一些可能区间,对每一个区间实行上面提到的O(n)算法即可。容易发现可能成为答案端点的位置不超过3e7,所以时间复杂度是3e7的。
Dirty Replay
- D题WA了一发,初始化的时候忘记把小于一个点编号的其它点删去了。
- F题WA了一发,一开始以计数的错误思路去做的,也没有测试太多样例直接浪交了。