2019.3.29
bzoj4709: [Jsoi2011]柠檬
好久没见斜率优化了…
这个题的斜率优化还有点非常规
首先发现一个性质,我们分段后,段的左右端点一定就是选取的贝壳,他们两个的颜色一样
否则显然可以把某些段缩小,答案单调不减
推一下式子就可以知道
2
∗
c
a
l
∗
s
[
i
]
∗
s
[
j
]
−
c
a
l
∗
s
[
i
]
2
+
f
[
i
]
=
f
[
j
]
+
c
a
l
∗
s
[
j
]
2
2*cal*s[i]*s[j]-cal*s[i]^2+f[i]=f[j]+cal*s[j]^2
2∗cal∗s[i]∗s[j]−cal∗s[i]2+f[i]=f[j]+cal∗s[j]2
其中
s
s
s表示某种颜色的前缀和
lyd牛逼现在才玩了一发正经斜率优化233
对于每种颜色维护一个上凸壳
但是询问斜率单调递增,并不是常规的队头
我们可以维护一个指针表示上一次取了哪个点作为答案,显然这个指针具有单调性
在单调栈上移动即可,并不需要二分2333
**bzoj4693: 雪中送温暖
所有东西都想到了但是就差一步…
首先容易发现,初始状态是红灯的仅有一个位置
所以本质上
就是求一个点到
(
1
,
1
,
1..1
)
(1,1,1..1)
(1,1,1..1)的方案数的奇偶性
设
a
i
=
x
i
−
1
a_i=x_i-1
ai=xi−1,那么不难写出式子就是
(
∑
a
i
)
!
Π
a
i
!
\frac{(\sum a_i)!}{\Pi a_i!}
Πai!(∑ai)!
然后就自闭了…
打表不难发现,当且仅当
∀
a
i
,
a
j
(
i
!
=
j
)
\forall a_i,a_j(i!=j)
∀ai,aj(i!=j)满足他们二进制位互不重叠时,才有贡献
那么直接数位dp即可
上下界容斥一下复杂度是很不满的
T
k
4
k
Tk4^k
Tk4k
em…
有时候还是要试试打表这个好东西
虽然可能打出来的东西…看不出来
2019.3.28
我又来更博客啦
*bzoj2159: Crash 的文明世界
听说GDOI2018有个弱化版,强行二项式套上去就能过的那种…
于是我就来这个题愉悦一下身心
以下设
n
=
d
i
s
t
(
i
,
j
)
n=dist(i,j)
n=dist(i,j)
他要求的是
n
k
n^k
nk,如果直接转移到
(
n
+
1
)
k
(n+1)^k
(n+1)k似乎是可以强行二项式维护的
有一个更优美的做法
把
n
k
n^k
nk写成第二类斯特林数的形式,那么就是
n
k
=
∑
i
=
1
m
i
n
(
n
,
k
)
S
(
k
,
i
)
∗
i
!
∗
C
n
i
n^k=\sum_{i=1}^{min(n,k)}S(k,i)*i!*C_{n}^{i}
nk=i=1∑min(n,k)S(k,i)∗i!∗Cni
把我们要求的东西套上去
∑
v
e
r
t
e
x
∑
i
=
1
m
i
n
(
n
,
k
)
S
(
k
,
i
)
∗
i
!
∗
C
n
i
\sum_{vertex} \sum_{i=1}^{min(n,k)}S(k,i)*i!*C_{n}^{i}
vertex∑i=1∑min(n,k)S(k,i)∗i!∗Cni
交换一下求和次序
∑
i
=
1
k
S
(
k
,
i
)
∗
i
!
∑
v
e
r
t
e
x
C
n
i
\sum_{i=1}^k S(k,i)*i!\sum_{vertex}C_{n}^{i}
i=1∑kS(k,i)∗i!vertex∑Cni
于是只需要维护后面的组合数和
注意到有式子
C
i
j
=
C
i
−
1
j
+
C
i
−
1
j
−
1
C_i^j=C_{i-1}^j+C_{i-1}^{j-1}
Cij=Ci−1j+Ci−1j−1
于是可以设
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示
i
i
i的子树内,所有点的
C
n
i
C_{n}^{i}
Cni的和
转移就是
f
[
x
]
[
i
]
=
∑
j
f
[
s
o
n
j
]
[
i
]
+
f
[
s
o
n
j
]
[
i
−
1
]
f[x][i]=\sum_{j} f[son_j][i]+f[son_j][i-1]
f[x][i]=j∑f[sonj][i]+f[sonj][i−1]
套一个换根dp就完事
2019.3.25
咕咕咕了好久啊qwq
*bzoj4872: [Shoi2017]分手是祝愿
首先发现
K
=
n
K=n
K=n的是有启发意义的
那么就是从后往前扫,扫到一个要被关掉的就关掉,然后枚举约数更改他们的状态
所以一个状态下,最小的更改次数是固定的
这样我居然骗到了80分的好成绩
不难发现,对于一个状态,操作他任意一个位置,要么会使得更改次数-1,要么使得他+1
所以可以设一个
d
p
[
i
]
dp[i]
dp[i]表示操作数为
i
i
i时做完次数的期望
d
p
[
i
]
=
i
n
(
d
p
[
i
−
1
]
+
1
)
+
n
−
i
n
(
d
p
[
i
+
1
]
+
1
)
dp[i]=\frac{i}{n}(dp[i-1]+1)+\frac{n-i}{n}(dp[i+1]+1)
dp[i]=ni(dp[i−1]+1)+nn−i(dp[i+1]+1)
边界
d
p
[
k
]
=
k
,
d
p
[
n
]
=
d
p
[
n
−
1
]
+
1
dp[k]=k,dp[n]=dp[n-1]+1
dp[k]=k,dp[n]=dp[n−1]+1,可以直接高斯消元
还有更简便的做法
把
f
f
f差分,那么得到一个
g
[
i
]
g[i]
g[i]表示从次数
i
i
i到次数
i
−
1
i-1
i−1的操作期望
g
[
i
]
=
i
n
+
n
−
i
n
∗
(
g
[
i
+
1
]
+
g
[
i
]
+
1
)
g[i]=\frac{i}{n}+\frac{n-i}{n}*(g[i+1]+g[i]+1)
g[i]=ni+nn−i∗(g[i+1]+g[i]+1)
这里我用我的理解意会了一下毕竟我写出来这玩意还不觉得他是对的…
就是你跑到后面了,你需要
g
[
i
+
1
]
g[i+1]
g[i+1]的次数来回来,然后还需要
g
[
i
]
g[i]
g[i]的次数往前走,其中需要额外的一步,根据期望的线性性大概这是对的??
然后随便移一下式子就没有了…
2019.3.11
雅礼集训Day8
2019.3.10
**bzoj4476: [Jsoi2015]送礼物
首先分数规划,然后一个
l
o
g
2
log^2
log2的算法就显然出来了…由于我常数太大所以跑不动
我们观察题目的限制,在大小在
[
L
+
1
,
R
]
[L+1,R]
[L+1,R]的串,显然左右端点分别是最大最小值时是最优的,否则一定可以去掉某一个位置使串长减小而贡献增大
当然对于长度为
L
L
L的串不一定以最大最小值为端点,所以这个暴力rmq做一次
不妨设右端点为
m
x
mx
mx,左端点为
m
n
mn
mn,然后反过来做一次
式子推一下就是
(
a
[
r
i
g
h
t
]
−
a
n
s
∗
r
i
g
h
t
)
−
(
a
[
l
e
f
t
]
−
a
n
s
∗
l
e
f
t
)
>
=
a
n
s
∗
K
(a[right]-ans*right)-(a[left]-ans*left)>=ans*K
(a[right]−ans∗right)−(a[left]−ans∗left)>=ans∗K
枚举右端点,用一个单调队列维护
a
[
i
]
−
a
n
s
∗
i
a[i]-ans*i
a[i]−ans∗i的最小值
注意这里有一个地方卡住了我…就是如果这样选择的话,右端点可能不一定能取到最大值的位置,左端点也不一定能取到最小值的位置。那与我们的规定违背啊…但是注意到,我们串长在
[
L
+
1
,
R
]
[L+1,R]
[L+1,R]时,一定是左右端点在最大值与最小值的时候时最优的,所以如果使得左右端点不合法的情况,这种情况是一定不优的,所以不会对答案有影响…
bzoj4475: [Jsoi2015]子集选取
分开考虑每一个数在哪些位置选了
如果用纵列来考虑,即一列一列考虑放了多少个的话
我们发现,第一列选择了
i
i
i个位置时,第二列只能选择不超过
i
−
1
i-1
i−1个,以此类推
那么其实相当于要选出若干不相等的数
所以一个数的贡献就是
2
k
2^k
2k,
n
n
n个数的总贡献就是
2
n
k
2^{nk}
2nk
bzoj4810: [Ynoi2017]由乃的玉米田
莫队套bitset
第一个询问相当于右移再与
第二个询问相当于把第一个位置变到哪里给找到,然后和反串与一下
第三个询问暴力做
2019.3.9
bzoj4821: [Sdoi2017]相关分析(口胡
把式子拆一拆
维护一下
x
i
,
y
i
,
x
i
2
x_i,y_i,x_i^2
xi,yi,xi2的区间和
第三个操作就是弄一个标记清空然后区间整体修改
注意一下标记的优先级
线段树维护即可
**bzoj4816: [Sdoi2017]数字表格
bzoj4818: [Sdoi2017]序列计数
首先显然可以跑一个
(
2
p
)
3
l
o
g
N
(2p)^3logN
(2p)3logN的做法…这个做法居然在loj和洛谷上能过
那么其实包含至少一个质数的情况就是总情况减去不合法情况
那么矩阵可以变成大小为
p
∗
p
p*p
p∗p的
注意到我们的转移矩阵是循环矩阵,那么快速幂的过程就可以优化成
p
2
p^2
p2了
2019.3.8
雅礼集训day7
2019.3.7
**bzoj4570: [Scoi2016]妖怪
先推一下就知道式子是
a
∗
x
+
1
a
∗
y
+
x
+
y
a*x+\frac{1}{a}*y+x+y
a∗x+a1∗y+x+y
找一个
a
a
a使得上式最大值最小
可以直接二分取交集但是跑不动
我们把每个妖怪扔到坐标系上,即
(
x
,
y
)
(x,y)
(x,y)
那么
a
(
a
<
0
)
a(a<0)
a(a<0)视为斜率
k
k
k,一个斜率
k
k
k对于妖怪的贡献就是与
x
,
y
x,y
x,y轴交点的坐标和
然后遇到这种几何最值优化的…一般要猜想在凸包上
这里安利一个证明
那么每个点先看看最值是不是在合法范围内,在就直接取min,否则看看在哪一侧就取哪一侧的边界来算…
**bzoj4569: [Scoi2016]萌萌哒
这题妙
直接并查集的话是
O
(
n
m
)
O(nm)
O(nm)的,线段树连边的话区间对应又做不动…
我们考虑有什么数据结构是区间一一对应的
ST表!
那么
f
a
[
i
]
[
j
]
fa[i][j]
fa[i][j]就表示
[
i
,
i
+
2
j
−
1
]
[i,i+2^j-1]
[i,i+2j−1]这段区间,在
2
j
2^j
2j下和哪些区间是一一对应的
这里对应用一个并查集…
那么每次类似线段树的pushdown
如果已经在一个并查集中了就不做了…
注意到每一层最多会合
N
N
N次,那么复杂度就是
N
l
o
g
N
NlogN
NlogN的了
bzoj4567: [Scoi2016]背单词
对反串建Tire,每个串向他最大的那个后缀连边
显然是一棵树…然后写了一个贪心水法莫名就过了
大概就是先按度数贪心,度数相同的时候按子树,小的优先…
肯定是个水法
bzoj4598: [Sdoi2016]模式字符串
把模式串先扩到大于
n
n
n的长度
然后正反哈希
大力点分,DFS子树的时候记录一下哈希值,然后就可以
O
(
1
)
O(1)
O(1)知道他是哪段前缀或者后缀
爱怎么算答案怎么算…
bzoj4556: [Tjoi2016&Heoi2016]字符串
SA建出来顺便一个主席树维护height连续一段出现了什么后缀
随意二分答案瞎check都能过…
bzoj4553: [Tjoi2016&Heoi2016]序列
d
o
w
n
i
,
c
a
l
i
,
u
p
i
down_i,cal_i,up_i
downi,cali,upi分别表示可能的最低值,初始值,可能的最高值
朴素dp的话只需要满足
u
p
j
≤
c
a
l
i
up_j\leq cal_i
upj≤cali并且
c
a
l
j
≤
d
o
w
n
i
cal_j \leq down_i
calj≤downi就可以从
j
j
j转移到
i
i
i
发现这是一个矩阵,可以二维线段树但是bz卡空间
差点就忘了cdq的另一种写法了…
先分治左边然后算右边的贡献再去分治右边啊qwq…
2019.3.6
雅礼集训Day2
bzoj4625: [BeiJing2016]水晶(口胡
拆成三排点
最小割完事…
2019.3.5
HAOI2018套题
在这里
似乎咕咕咕了几天
2019.3.3
bzoj5306: [Haoi2018]染色
2019.3.2
**bzoj5302: [Haoi2018]奇怪的背包
恕我菜了
裴蜀定理都没想到
推广一下可以知道要使得
∑
a
i
x
i
=
c
a
l
\sum a_ix_i = cal
∑aixi=cal
需要满足
g
c
d
(
a
1
,
a
2
,
.
.
.
,
a
n
)
∣
c
a
l
gcd(a_1,a_2,...,a_n)|cal
gcd(a1,a2,...,an)∣cal
这里对
p
p
p取模可以看作减去
p
∗
x
p*x
p∗x
那么一个方案
a
1
,
a
2
,
.
.
,
a
n
a_1,a_2,..,a_n
a1,a2,..,an合法只需要知道他们与
p
p
p的
g
c
d
gcd
gcd是
x
x
x的因数
先预处理
f
[
i
]
f[i]
f[i]表示是
p
p
p的第
i
i
i个因数的倍数的数有多少个
简单容斥可以得到
g
[
i
]
g[i]
g[i]表示
g
c
d
=
i
gcd=i
gcd=i的数对有多少对
复杂度通过子集倍数积可
n
2
n^2
n2得到
回答套一个map就可以
l
o
g
log
log做了
bzoj4857: [Jsoi2016]反质数序列
n
2
n^2
n2可以找出不合法的点对是什么
什么这是一般图最大独立集??
用奇偶黑白染色
显然知道两边集合内都不会有边相连
特判1只能有一个
连边最小割即可
bzoj4855: [Jsoi2016]轻重路径
容易知道只需要维护一个点到根的轻重链信息
删点不是很好做,因为可能重链会变轻链
变换为加点,容易发现这时候重链不会更改,只有轻链可能变换为重链
不考虑题目在线限制的话只需要维护每个点的子树大小与和父亲链是否是重链信息即可
这个一个树剖可以做到
注意到题目有在线限制虽然是假的
我们提取出某一个非重链的点时,如果他和他的兄弟子树大小相同,那么需要判断
显然这时候只需要知道,他们两个子树内最后一个被删除的点是什么时候被删除的,显然后删除的那个作为重链
DFS序+线段树维护即可
2019.3.1
**bzoj4854: [Jsoi2016]无界单词
bzoj4853: [Jsoi2016]飞机调度
把每个任务做完后可以支援到的下一个任务连边
发现这是一个DAG
那直接DAG最小链覆盖
bzoj4851: [Jsoi2016]位运算
不考虑相同限制的话可以压
2
7
2^7
27表示每个位是否顶格,矩阵转移
否则的话我们考虑强行有序
让
[
2
,
n
]
[2,n]
[2,n]位表示每个位置是否和前面相同,第一个位置表示是否顶格
转移也注意强行有序即可
bzoj1396: 识别子串
挺傻的…考虑以每个点为开头的后缀的前缀的贡献
把SA和height建出来,那一个串在超过
m
a
x
(
h
e
i
g
h
t
[
i
−
1
]
,
h
e
i
g
h
t
[
i
+
1
]
)
max(height[i-1],height[i+1])
max(height[i−1],height[i+1])的位置就是唯一的了
线段树随意维护
2019.2.28
JXOI2018套题
**bzoj5460: Set
这题恕我菜了
设一个全部的异或和为
t
e
m
p
temp
temp
那么要求最大化
x
1
+
(
t
e
m
p
⊕
x
1
)
x1+(temp\oplus x1)
x1+(temp⊕x1)
对
t
e
m
p
temp
temp的第
i
i
i位是
0
/
1
0/1
0/1分类讨论,可知如果第
i
i
i位为0的时候,
x
1
x1
x1的第
i
i
i位为1会更优秀
否则是0是1都无影响
首要是要满足最大化和,齐次最小化
x
1
x1
x1
那么根据这一位是
0
0
0的话确定一下这个是不是让和最大化的关键位置
分两个关键字插入线性基
假如能作为和最大化的东西,那么就优先插入和的位置
否则插入让
x
1
x1
x1最小化的位置
因为插入让
x
1
x1
x1最小化的位置的数,是不会影响插入和的贡献的
最后根据插入顺序再做线性基上贪心取值
bzoj4754: [Jsoi2016]独特的树叶
树哈希
随意想了一个哈希方法就是
h
s
[
x
]
=
b
a
s
e
∗
(
Π
h
s
[
s
o
n
]
+
t
o
t
[
x
]
)
hs[x]=base*(\Pi hs[son]+tot[x])
hs[x]=base∗(Πhs[son]+tot[x])
其中
t
o
t
[
x
]
tot[x]
tot[x]表示
x
x
x的子树和
上式是可以换根
d
p
dp
dp的所以可以
O
(
n
)
O(n)
O(n)求出以每个点为根的哈希值
注意到是无根的所以先求出以
A
A
A树的每个点为根的哈希值存入一个
s
e
t
set
set里
再对
B
B
B树
d
p
dp
dp,换根换到下一个点是叶子的时候就看看去掉那个点的哈希值在
s
e
t
set
set中是否存在
存在证明那个叶子是合法的
bzoj4337: BJOI2015 树的同构
同上
bzoj4539: [Hnoi2016]树
我们把每次插入的连通块看作一个点
然后就可以得到一张新图
新图维护一个倍增数组知道
2
i
2^i
2i祖先是哪个连通块
同时维护一个
s
u
m
[
x
]
sum[x]
sum[x]表示从第
x
x
x个块的根到原树的根的长度和
那么对于两个点的距离就根据在新图上的位置讨论一下就可求了
注意到可能要求某个点在原树上的编号
其实就是找一个子树第
K
K
K大
那么就被强行套上了一个主席树…
话说真的好拼题啊
bzoj4755: [Jsoi2016]扭动的回文串
理性证明对于一个点
i
i
i
一定是在
A
A
A上选择一个以他为中心的最长回文串,然后再在
A
A
A和
B
B
B上选最长相同
或者在
B
B
B上选择一个以他为中心的最长回文串,然后同上
直接二分哈希分类讨论
如果你不喜欢
l
o
g
log
log的话可以换成后缀数组
毫不注重常数于是bz跑了8s…
2019.2.27
**bzoj5319: [Jsoi2018]军训列队
首先肯定是排第一的去第一个 排第二的去第二个…以此类推
那么就需要找到一个位置
m
i
d
mid
mid使得
m
i
d
−
K
+
1
=
a
[
m
i
d
]
mid-K+1=a[mid]
mid−K+1=a[mid]
其中
a
[
m
i
d
]
a[mid]
a[mid]表示
[
1
,
m
i
d
]
[1,mid]
[1,mid]中,编号在
[
L
,
R
]
[L,R]
[L,R]的人数
朴素可以
n
l
o
g
2
n
nlog^2n
nlog2n的二分+主席树
但是可以直接在主席树上二分
注意主席树上二分的玩法
对于区间不是完整的,有两种做法
你可以把区间裂开成
l
o
g
log
log个,然后找到答案在哪个区间中,然后再变为完整的区间进入主席树
或者直接二分
具体看代码
bzoj5315: [Jsoi2018]防御网络
注意到
n
=
200
n=200
n=200所以可以各种随意跑
一看就是考虑每条边贡献的题
又发现这是一个点仙人掌所以更好做了…
非环边会被算到的贡献就是
(
2
t
o
t
[
x
]
−
1
)
∗
(
2
t
o
t
[
y
]
−
1
)
(2^{tot[x]}-1)*(2^{tot[y]}-1)
(2tot[x]−1)∗(2tot[y]−1),分别表示上面的节点数和下面的节点数
考虑环边怎么做,我们可以设一个
d
p
[
i
]
[
j
]
[
k
]
dp[i][j][k]
dp[i][j][k]表示选中环上第
i
i
i与第
j
j
j个点,选中了任意连续两点之间的差的最大值是
k
k
k的方案数
那么最后枚举一下
i
,
j
,
k
i,j,k
i,j,k,然后就可以知道哪段边要断掉,贡献就容易算出了
转移就分类讨论
先是枚举
j
j
j和
j
j
j之前一段作为最大值那么
∑
u
u
<
=
k
d
p
[
i
]
[
j
−
k
]
[
u
]
\sum_u^{u<=k} dp[i][j-k][u]
∑uu<=kdp[i][j−k][u]
否则的话就是
∑
u
=
j
−
k
+
1
j
−
1
d
p
[
i
]
[
u
]
[
k
]
\sum_{u=j-k+1}^{j-1}dp[i][u][k]
∑u=j−k+1j−1dp[i][u][k]
注意到都可以前缀和优化那么就是优越的
n
3
n^3
n3了
51nod1462 树据结构
开始脑子瓦特了想了个假做法
n
l
o
g
2
n
nlog^2n
nlog2n的做法容易想到dsu on tree,每个加标记的贡献就是时间点在他后面的乘标记的和
这个用一个树状数组维护
但是还有更简单的做法,思考一下前后合并的过程
其实可以直接线段树合并
那么就是
n
l
o
g
n
nlogn
nlogn的了
bzoj5291: [Bjoi2018]链上二次求和
睡醒了就会做了
设
a
[
i
]
a[i]
a[i]表示原数组的前缀和
下边界容斥掉
分类讨论每个
a
[
i
]
a[i]
a[i]减去和加上的次数
对于
[
1
,
n
−
r
]
[1,n-r]
[1,n−r],减了
r
r
r次。对于
[
n
−
r
+
1
,
n
]
[n-r+1,n]
[n−r+1,n],减了
(
r
−
i
+
1
)
(r-i+1)
(r−i+1)次
对于
[
r
+
1
,
n
]
[r+1,n]
[r+1,n],加了
r
r
r次。对于
[
1
,
r
]
[1,r]
[1,r],加了
i
i
i次
于是只需要维护
a
[
i
]
∗
i
a[i]*i
a[i]∗i与
a
[
i
]
a[i]
a[i]的区间和即可
考虑区间
[
l
,
r
]
[l,r]
[l,r]加
d
d
d,第
u
u
u个位置会加上多少个
d
d
d
对于
a
[
i
]
a[i]
a[i]的和,他加上了
u
∗
d
−
d
∗
(
l
−
1
)
u*d-d*(l-1)
u∗d−d∗(l−1)
对于
a
[
i
]
∗
i
a[i]*i
a[i]∗i,他加上了
u
2
∗
d
−
u
∗
d
∗
(
l
−
1
)
u^2*d-u*d*(l-1)
u2∗d−u∗d∗(l−1)
线段树随意维护一下即可
**bzoj5289: [Hnoi2018]排列
转化一下就是lyd书上的原题了啊…
看懂题之后就是让每个点从
a
[
i
]
a[i]
a[i]向他自己连边
可以知道这是一个森林,那就加一个虚点不影响答案
需要满足每个点染色前 父亲被染过色了 第
i
i
i次染色的贡献是
i
∗
b
[
i
]
i*b[i]
i∗b[i],要求最大化贡献
听说考场上优先队列80pts???
原题似乎是poj2054
可以提炼一个性质,就是当前未被染色的最小点一定会在他的父亲被染色后立即染色
瞎转化后可以变为每次取出 连通块权值/连通块点数 最小的连通块,把他和他父亲的连通块并在一起,并且让这个连通块的删除顺序接在父亲最后一个删除的后面
用一个可删堆维护即可