ps:主要是把之前做的有点意思的题总结一下
- CF1129D Isolation
思维难度: (8) 分块优化 D P DP DP确实是没写过,也没想过,听提示才想到的
代码难度: (5)
sol:
首先不难想到考虑扫描线,对于每个左端点,记录
g
s
[
l
]
gs[l]
gs[l]表示
[
l
.
.
.
r
]
[l...r]
[l...r]出现次数为
1
1
1的数的个数
然后对于每加入的一个
i
i
i,即上一个和
i
i
i一样的是
l
s
t
[
i
]
lst[i]
lst[i],相当于是把
[
l
s
t
[
l
s
t
[
i
]
]
.
.
.
l
s
t
[
i
]
−
1
]
[lst[lst[i]]...lst[i]-1]
[lst[lst[i]]...lst[i]−1]的
−
1
-1
−1,把
[
l
s
t
[
i
]
.
.
.
.
i
−
1
]
[lst[i]....i-1]
[lst[i]....i−1]的
+
1
+1
+1
考虑分块,对于每一块,记录
g
s
[
l
]
≤
x
gs[l] \le x
gs[l]≤x的数量,
注意到每块 g s [ l ] gs[l] gs[l]的最大最小值不会超过 n \sqrt{n} n所以之需要保留这么多的就行了
时间复杂度 O ( n n ) O(n\sqrt{n}) O(nn),空间复杂度 O ( n ) O(n) O(n)
code
- CF833B The Bakery
思维难度: (6)
代码难度: (4.5)
sol:
猜一手具有决策单调性,分治优化
D
P
DP
DP即可
code
- luogu P2289 [HNOI2004]邮递员
思维难度: (7.5)
代码难度: (7.5)
复习一下插头DP
sol:
和模板一样,只不过要用__int128
code
- AT2673 [AGC018D] Tree and Hamilton Path
思维难度: (7.5)
代码难度: (3)
想了一半,没想出来
sol:
首先如果是回路的话,假设一条边两遍的大小分别是
s
i
z
[
u
]
,
s
i
z
[
v
]
siz[u],siz[v]
siz[u],siz[v],一条边的贡献是
c
∗
m
i
n
(
s
i
z
[
u
]
,
s
i
z
[
v
]
)
c*min(siz[u],siz[v])
c∗min(siz[u],siz[v])
这样是一定可以构造出来的,但是这题求的是路径,那么要在回路中选一条边割掉,一开始的想法是在树上找一条最小的边割掉,但是这条边不一定会在回路中,所以不对
画画图后不难得到,回路中的每条边一定会经过树的重心,否则肯定不是最长的,于是找到树的重心,然后找和重心相连的最小的一条边即可(即回路从重心出发,然后割掉这条边,变成路径)
如果有两个重心就是两重心中间的那条边
code
- AT2363 [AGC012C] Tautonym Puzzle
思维难度: (7) 没想出来,降智了
代码难度: (3)
sol:
题解区的不会写题解可以不写,别自己都没想清楚就在那xjb写,跟风错得一个样
观察到字符集的大小为
100
100
100,长度为
200
200
200,暗示我们要把序列分为两部分,假设后半部分为
1
,
.
.
.
,
100
1,...,100
1,...,100
考虑前半部分从小到大填,如果填最前面,就会使答案
+
1
+1
+1,如果填后面就会使答案
∗
2
+
1
*2+1
∗2+1
于是就可以分治下去做了,如果当前位是偶数就在前面填一个,然后处理 n − 1 n-1 n−1,否则就在后面填一个,处理 ( n − 1 ) > > 1 (n-1)>>1 (n−1)>>1
code
- luogu P4798 [CEOI2015 Day1]卡尔文球锦标赛
思维难度: (6)
代码难度: (4)
sol:
哈皮数位
D
P
DP
DP,设
f
[
i
]
[
j
]
[
0
/
1
]
f[i][j][0/1]
f[i][j][0/1] 表示考虑前
i
i
i个,当前最大的是
j
j
j,是否卡上界
转移就分几种情况转移
f
[
i
+
1
]
[
j
]
[
0
]
+
=
f
[
i
]
[
j
]
[
0
]
∗
j
f[i+1][j][0]+= f[i][j][0]*j
f[i+1][j][0]+=f[i][j][0]∗j (不卡上界,下一位瞎填)
f
[
i
+
1
]
[
j
+
1
]
[
0
]
+
=
f
[
i
]
[
j
]
[
0
]
f[i+1][j+1][0]+= f[i][j][0]
f[i+1][j+1][0]+=f[i][j][0] (不卡上界,下一位新开一个填)
f
[
i
+
1
]
[
j
]
[
0
]
+
=
(
a
[
i
+
1
]
−
1
)
∗
f
[
i
]
[
j
]
[
1
]
f[i+1][j][0]+= (a[i+1]-1)*f[i][j][1]
f[i+1][j][0]+=(a[i+1]−1)∗f[i][j][1] (这一位卡上界,下一位不卡上界)
f [ i + 1 ] [ j + 0 / 1 ] [ 1 ] + = f [ i ] [ j ] [ 1 ] f[i+1][j+0/1][1]+= f[i][j][1] f[i+1][j+0/1][1]+=f[i][j][1] (卡上界,下一位也卡上界,+1看下一位是不是 j + 1 j+1 j+1)
code
- luogu P4559 [JSOI2018]列队
思维难度: (6.5)
代码难度: (5)
sol:
这个叫啥?势能线段树?
不难想到分三种情况,全部学生往右跑,全部学生往左跑,一部分往左,一部分往右
前两种直接返回答案,最后一种递归下去做
时间复杂度是正确的
用主席树维护即可
code
- luogu P3293 [SCOI2016]美味
思维难度: (6)
代码难度: (5)
sol:
典中典了属于是
异或最大值不难想到从高位往地位贪心,应为涉及到
+
x
+x
+x,所以可以直接在
[
2
k
−
x
,
2
k
+
1
−
x
)
[2^k-x, 2^{k+1}-x)
[2k−x,2k+1−x)的这段区间里面找是否存在数,找下去即可
code