2021.7.5A组
t1 考虑二分一个
m
i
d
mid
mid,设
f
i
f_i
fi为将
1
∼
i
1\sim i
1∼i的单词全部放入横行中并且最大的间隔是否能小于
m
i
d
mid
mid,容易发现能转移到
f
i
f_i
fi的为一段区间
l
i
∼
r
i
l_i\sim r_i
li∼ri,且
∀
i
≤
j
,
l
i
≤
l
j
,
r
i
≤
r
j
\forall i\le j,l_i\le l_j,r_i\le r_j
∀i≤j,li≤lj,ri≤rj,所以就可以
O
(
n
)
O(n)
O(n)实现
c
h
e
c
k
check
check
t2 设
c
i
,
j
c_{i,j}
ci,j为第
i
i
i格后的第一格字符
j
j
j的位置,设
f
s
f_{s}
fs为状态为
s
s
s的所有单词同时能够找到的最前的位置
容易得到转移:
f
s
=
max
i
∈
s
c
f
s
−
(
1
<
<
i
)
,
i
f_s=\max_{i\in s} c_{f_{s-(1<<i)},i}
fs=maxi∈scfs−(1<<i),i
但是当
n
>
21
n>21
n>21时,状压跑不动了,网上说直接输出
N
O
NO
NO,原因好像是因为长度下线为
n
2
−
n
+
1
≥
450
n^2-n+1\ge 450
n2−n+1≥450
t3
区间筛,先筛出
[
1
,
1
0
6
]
[1,10^6]
[1,106]的质数,那么
[
1
,
1
0
14
]
[1,10^{14}]
[1,1014]的数一定可以被
[
1
,
1
0
6
]
[1,10^6]
[1,106]的质数分解,剩下的数要么为
1
1
1,要么为质数
2021.7.6A组
t1 状压
d
p
dp
dp,设
f
s
f_{s}
fs为将属于
s
s
s的点连接起来的最小代价,将和为
0
0
0的状态拿出来在做一次
d
p
dp
dp即可
t2 不开
l
o
n
g
l
o
n
g
long\ long
long long见祖宗,考场时处理车站写了换根
d
p
dp
dp,事实上直接把车站看成一个点就行了
t3 只会
n
=
1
n=1
n=1的情况,设
f
i
f_i
fi为走到前缀
i
i
i的期望步数,如果要走到前缀
i
i
i,首先必须要走到前缀
i
−
1
i-1
i−1,前缀
i
−
1
i-1
i−1可能直接走到
i
i
i,或者走到一个失配前缀
x
x
x,容易得到
f
i
=
1
2
(
f
i
−
1
+
1
)
+
1
2
(
f
i
−
1
+
1
+
f
i
−
f
x
)
f_i=\frac{1}{2}(f_{i-1}+1)+\frac{1}{2}(f_{i-1}+1+f_i-f_x)
fi=21(fi−1+1)+21(fi−1+1+fi−fx),移项得
f
i
=
2
f
i
−
1
+
2
−
f
x
f_i=2f_{i-1}+2-f_x
fi=2fi−1+2−fx
x
x
x可以用
k
m
p
kmp
kmp得到,就可以直接顺推了
2021.7.7A组
t1 斯坦纳树,之前做过,结果写错了,设
f
i
,
s
f_{i,s}
fi,s为以
i
i
i为根的树,关键点联通状态为
s
s
s时的最小代价,第一种转移,枚举子集合并
f
i
,
s
=
min
s
′
∈
s
f
i
,
s
′
,
f
i
,
s
−
s
′
f_{i,s}=\min\limits_{s'\in s} f_{i,s'},f_{i,s-s'}
fi,s=s′∈sminfi,s′,fi,s−s′,第二种转移,换根
f
v
,
s
=
f
u
,
s
+
w
f_{v,s}=f_{u,s}+w
fv,s=fu,s+w
,第二种转移可以用
s
p
f
a
spfa
spfa实现,最后在做一个类似背包的合并即可
t2 赛后才理解题意,首先可以发现一个性质,两个无根树同构,当且仅当以这两棵无根树的中心为根的有根树同构,所以首先找到重心,如果重心有两个,就把边断开再新加入一个点,使重心变为一个,判断有根树是否同构可以使用
h
a
s
h
hash
hash判断
设
f
x
,
y
f_{x,y}
fx,y为使以
x
x
x和
y
y
y为根的两课同构子树相同的最小代价,转移就是用
x
x
x和
y
y
y的儿子互相配对,可以用
K
M
KM
KM或费用流实现
t3 只会前四个
s
u
b
t
a
s
k
subtask
subtask,设
f
(
i
)
f(i)
f(i)为让数
i
i
i变为
0
0
0的期望步数,容易发现
f
(
i
)
=
f
(
i
⋅
2
j
)
f(i)=f(i\cdot 2^j)
f(i)=f(i⋅2j),那么当
i
≠
1
i\ne 1
i=1时,无论如何转移
i
i
i都会变小,当
i
=
1
i=1
i=1时可以列出方程
f
(
1
)
=
a
b
(
f
(
1
)
+
1
)
+
(
1
−
a
b
)
(
f
(
0
)
+
1
)
f(1)=\frac{a}{b}(f(1)+1)+(1-\frac{a}{b})(f(0)+1)
f(1)=ba(f(1)+1)+(1−ba)(f(0)+1),由
f
(
0
)
=
0
f(0)=0
f(0)=0,得到
f
(
1
)
=
b
b
−
a
f(1)=\frac{b}{b-a}
f(1)=b−ab,于是就可以递归求解,加个记忆化就可以得到
40
p
t
s
40pts
40pts
2021.7.9A组
t1 先将
a
,
b
a,b
a,b约分,容易发现答案与
a
a
a无关,若
g
c
d
(
b
,
k
)
=
1
gcd(b,k)=1
gcd(b,k)=1,相当于求一个最小的
x
x
x,使得
k
x
≡
1
(
m
o
d
b
)
k^x\equiv 1\pmod b
kx≡1(modb),因为
k
φ
(
b
)
≡
1
k^{\varphi(b)}\equiv 1
kφ(b)≡1,所以
x
x
x为
φ
(
b
)
\varphi(b)
φ(b)的约数,试除法即可,若
g
c
d
(
b
,
k
)
≠
1
gcd(b,k)\ne 1
gcd(b,k)=1,那每乘一次
k
k
k,都会将
b
b
b约去
g
c
d
(
b
,
k
)
gcd(b,k)
gcd(b,k),所以不断将
b
b
b除去
g
c
d
(
b
,
k
)
gcd(b,k)
gcd(b,k)直到
g
c
d
(
b
,
k
)
=
1
gcd(b,k)=1
gcd(b,k)=1,除去次数为混循环长度,然后就可以套用前面的做法
t2 四维偏序,时间为第一维,
c
d
q
cdq
cdq分治处理第二维
x
x
x,树状数组处理第三维,线段树处理第四维,每次
c
d
q
cdq
cdq完一层之后,都将线段树结点清空,可以大大减小常数
t3 将题目分成两个部分
第一部分,先求不同构珠子的数量,容斥可求
第二部分,设不同构珠子数量为
c
c
c,
f
(
i
)
f(i)
f(i)为长度为
i
i
i的环的长度方案,运用
p
o
l
y
a
polya
polya定理即可得出答案为:
∑
i
=
1
n
f
(
g
c
d
(
i
,
n
)
)
\sum_{i=1}^nf(gcd(i,n))
i=1∑nf(gcd(i,n))
=
∑
d
∣
n
f
(
d
)
φ
(
n
d
)
=\sum_{d|n}f(d)\varphi(\frac{n}{d})
=d∣n∑f(d)φ(dn)
=
∑
d
∣
n
φ
(
d
)
f
(
n
d
)
=\sum_{d|n}\varphi(d)f(\frac{n}{d})
=d∣n∑φ(d)f(dn)
枚举因数即可
O
(
n
)
O(\sqrt n)
O(n)求出答案
2021.7.10A组
t1 先在模意义下差分,然后操作变成让一个数+1,另一个数-1,或只让一个数+1或-1,贪心即可
t2 分数规划,二分一个
m
i
d
mid
mid,然后题目转化为gmoj5432三元组
t3 未知
t4 如果一个字符串是对称的,那它一定可以被分成两个回文串,将字符串翻一倍,用马拉车求出每个字符的回文半径,对于每个
i
i
i求出一个
j
j
j使得
j
+
h
w
j
>
i
−
h
w
i
+
1
,
i
−
j
≤
n
j+hw_j>i-hw_i+1,i-j\le n
j+hwj>i−hwi+1,i−j≤n,并使
i
−
j
i-j
i−j最大,线段树实现
2021.7.12A组
t1 不难发现,操作之间可以合并,设
f
i
,
j
f_{i,j}
fi,j为
T
T
T串以
i
i
i开头,
S
S
S串以
j
j
j开头的最长匹配长度,考虑从
f
i
+
1
,
j
+
1
f_{i+1,j+1}
fi+1,j+1转移到
f
i
,
j
f_{i,j}
fi,j,看
j
j
j所在块能否有剩余的
T
i
T_i
Ti字母来填补,如果有,那么
f
i
,
j
=
f
i
+
1
,
j
+
1
+
1
f_{i,j}=f_{i+1,j+1}+1
fi,j=fi+1,j+1+1
否则判段已经匹配的段中是否有
T
i
T_i
Ti字母,如果有,找到最后一个
T
i
T_i
Ti的位置,令之为
k
k
k,则
f
i
,
j
=
k
−
j
f_{i,j}=k-j
fi,j=k−j,否则
f
i
,
j
=
0
f_{i,j}=0
fi,j=0
t2 首先给出一个定理,一个偏序集的最长反链长度为偏序集大小减去最大链匹配数,先跑一遍
f
l
o
y
e
d
floyed
floyed求出偏序集中元素的关系,然后用匈牙利算法求出最大链匹配数
t3 极其恶心的线段树,还没有调出来,先考虑什么样的区间能被
3
3
3整除,如果
1
1
1的个数为偶,显然合法,如果
1
1
1的个数为奇数,当
L
(
1
)
=
1
L(1)=1
L(1)=1时,不合法,当
L
(
0
)
≤
1
L(0)\le 1
L(0)≤1时,不合法
考虑求出不合法的数量,然后用总集减去不合法数量,即为合法数量,线段树维护
10
10
10个元素,
s
u
m
,
l
e
n
,
l
0
,
l
1
,
r
0
,
r
1
,
l
01
,
l
10
,
r
01
,
r
10
sum,len,l0,l1,r0,r1,l01,l10,r01,r10
sum,len,l0,l1,r0,r1,l01,l10,r01,r10,分
4
4
4种情况讨论计算
t4 未知
2021.7.13A组
t1 考虑使用费用流解决,思考如何建图,建立超级源点
s
s
s和超级汇点
t
t
t,用
n
n
n个点表示横行,
m
m
m个点表示竖行,
s
s
s向每个表示横行的点连一条流量为
2
2
2,费用为
0
0
0的边,表示每个横行最多选
2
2
2块地,每个表示竖行的点向
t
t
t连一条流量为
2
2
2,费用为
0
0
0的点,表示每个竖行最多选两个块,对于一个
a
i
,
j
a_{i,j}
ai,j,我们让第
i
i
i个横行的点向第
j
j
j个竖行的点连一条流量为
1
1
1,费用为
a
i
,
j
a_{i,j}
ai,j的边,跑最大费用即可,注意不需要最大流,所以当
d
i
s
≤
0
dis\le 0
dis≤0时,就可以停止程序
t2 考虑双标记线段树,推出一个标记下传时对其他标记的影响,出现点被毁坏时,暴力找出并删除,由于每个点最多被删一次,所以复杂度是对的
t3
∑
i
=
1
n
∑
d
∣
n
(
d
,
n
d
)
\sum_{i=1}^n\sum_{d|n}(d,\frac{n}{d})
i=1∑nd∣n∑(d,dn)考虑用
i
i
i和
j
j
j枚举
d
d
d和
n
d
\frac{n}{d}
dn
∑
i
=
1
n
∑
j
=
1
⌊
n
i
⌋
(
i
,
j
)
\sum_{i=1}^n\sum_{j=1}^{\lfloor\frac{n}{i}\rfloor}(i,j)
i=1∑nj=1∑⌊in⌋(i,j)欧拉反演
∑
i
=
1
n
∑
j
=
1
⌊
n
i
⌋
∑
d
∣
i
,
d
∣
j
φ
(
d
)
\sum_{i=1}^n\sum_{j=1}^{\lfloor\frac{n}{i}\rfloor}\sum_{d|i,d|j}\varphi(d)
i=1∑nj=1∑⌊in⌋d∣i,d∣j∑φ(d)
∑
d
=
1
n
φ
(
d
)
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
n
i
d
2
⌋
1
\sum_{d=1}^n\varphi(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{id^2}\rfloor}1
d=1∑nφ(d)i=1∑⌊dn⌋j=1∑⌊id2n⌋1
∑
d
=
1
n
φ
(
d
)
∑
i
=
1
⌊
n
d
⌋
⌊
n
i
d
2
⌋
\sum_{d=1}^n\varphi(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\lfloor\frac{n}{id^2}\rfloor
d=1∑nφ(d)i=1∑⌊dn⌋⌊id2n⌋由于当
i
>
n
d
2
i>\frac{n}{d^2}
i>d2n时,
⌊
n
i
d
2
⌋
=
0
\lfloor\frac{n}{id^2}\rfloor=0
⌊id2n⌋=0,所以
∑
d
=
1
n
φ
(
d
)
∑
i
=
1
⌊
n
d
2
⌋
⌊
n
i
d
2
⌋
\sum_{d=1}^n\varphi(d)\sum_{i=1}^{\lfloor\frac{n}{d^2}\rfloor}\lfloor\frac{n} {id^2}\rfloor
d=1∑nφ(d)i=1∑⌊d2n⌋⌊id2n⌋同理
∑
d
=
1
n
φ
(
d
)
∑
i
=
1
⌊
n
d
2
⌋
⌊
n
i
d
2
⌋
\sum_{d=1}^{\sqrt n}\varphi(d)\sum_{i=1}^{\lfloor\frac{n}{d^2}\rfloor}\lfloor\frac{n}{id^2}\rfloor
d=1∑nφ(d)i=1∑⌊d2n⌋⌊id2n⌋
用
φ
\varphi
φ筛法预处理,后面数论分块,即可做到
O
(
n
log
n
)
O(\sqrt n\log n)
O(nlogn)的时间复杂度
2021.7.15A组
t1 求一个最小的
k
k
k使得
n
∣
∑
i
=
1
k
i
n|\sum_{i=1}^ki
n∣∑i=1ki,即
n
∣
k
(
k
+
1
)
2
,
2
n
∣
k
(
k
+
1
)
n|\frac{k(k+1)}{2},2n|k(k+1)
n∣2k(k+1),2n∣k(k+1),由于
k
k
k与
k
+
1
k+1
k+1互质,所以
2
n
2n
2n中的因数可以被分为互质的两部分
a
a
a和
b
b
b,使得
a
∣
k
,
b
∣
k
+
1
a|k,b|k+1
a∣k,b∣k+1,设
k
=
a
x
,
k
+
1
=
b
y
k=ax,k+1=by
k=ax,k+1=by,得到
−
a
x
+
b
y
=
1
-ax+by=1
−ax+by=1,使用扩展欧几里得求出
x
x
x的最大负整数解代入求
k
k
k即可,先将
2
n
2n
2n分解质因数,
a
,
b
a,b
a,b可以
d
f
s
dfs
dfs暴力枚举,注意要先用线筛筛一遍质数,不然会
t
l
e
tle
tle
t2 假设只有一个点,每次扩展都会有许多无用扩展,记
a
i
a_i
ai为实际扩展长度,若向右扩展为正数,向左扩展为负数,考虑两个点之间的贡献,令两点距离为
d
d
d,当前时刻为
k
k
k,若
∑
i
=
1
k
∣
a
i
∣
≥
d
\sum_{i=1}^k|a_i|\ge d
∑i=1k∣ai∣≥d,则说明它们之间的有用区间都已经用完了,考虑求出最小的
k
k
k使得
∑
i
=
1
k
∣
a
i
∣
≤
d
\sum_{i=1}^k|a_i|\le d
∑i=1k∣ai∣≤d,
a
i
a_i
ai的正数和为前面那个点向右扩展的贡献,
a
i
a_i
ai的负数和为后面面那个点向左扩展的贡献,如果中间还有空缺,在找出哪个点最先扩展,将贡献计入那个点,提前按它们之间的距离排序,就可以做到
O
(
n
)
O(n)
O(n)复杂度
t3 喜闻乐见的网络流,假设我们先将所有的人都雇佣了但是还未付工资,设边权和为
s
u
m
sum
sum,让源点
s
s
s向
i
i
i点连一条大小为
c
i
c_i
ci的边,
c
i
c_i
ci表示雇佣
i
i
i的价格,
i
i
i点向汇点
t
t
t连一条大小为
∑
j
=
1
n
e
i
,
j
\sum_{j=1}^ne_{i,j}
∑j=1nei,j的边,
i
i
i点向
j
j
j点连一条大小为
2
a
i
,
j
2a_{i,j}
2ai,j的边,跑最小割,考虑割的含义:
1.
1.
1.如果割了一条
s
s
s到
i
i
i的边,说明我们雇佣了
i
i
i这个点,要减去
c
i
c_i
ci
2.
2.
2.如果割了一条
i
i
i到
t
t
t的边,说明我们没有雇佣
i
i
i这个点,要减去
∑
j
=
1
n
e
i
,
j
\sum_{j=1}^ne_{i,j}
∑j=1nei,j
3.
3.
3.对于点对
(
i
,
j
)
(i,j)
(i,j),如果
s
s
s到
i
i
i的边没割,
i
i
i到
t
t
t的边也没有割,那
i
i
i到
j
j
j的边就必须割,不仅没有原来的
e
i
,
j
e_{i,j}
ei,j,还会被减去
e
i
,
j
e_{i,j}
ei,j
所以是对的
t4 由于不同的字符要恰好等于
3
3
3,那么我们将
64
64
64位数拍成四组
16
16
16位数,四组数中必定有一组相等,利用这组相等的数作为检索,就减小比较的次数,可以被构造数据卡掉,但数据随机,所以能过
2021.8.9A组
t1 首先用
t
a
r
j
a
n
tarjan
tarjan将图变成
DAG
\text{DAG}
DAG图,然后对于每个联通块求出最大链,取最大的
k
+
1
k+1
k+1条链相加
t2 先将一个班的同学视为相同的人,最后再讲答案乘上
∏
i
=
1
n
a
i
!
\prod_{i=1}^na_i!
∏i=1nai!即可,设
f
i
,
j
f_{i,j}
fi,j表示前
i
i
i个班的同学排在一起,组成
j
j
j对同班相邻的方案数,
f
n
,
0
f_{n,0}
fn,0即为答案,令
s
i
=
∑
j
=
1
i
a
j
s_i=\sum_{j=1}^ia_j
si=∑j=1iaj,可以得到:
f
i
+
1
,
j
+
a
i
+
1
−
k
−
t
=
∑
k
=
1
a
i
+
1
∑
t
=
1
min
(
j
,
k
)
f
i
,
j
C
j
t
C
a
i
+
1
−
1
k
−
1
C
s
i
+
1
−
j
k
−
t
f_{i+1,j+a_{i+1}-k-t}=\sum_{k=1}^{a_{i+1}}\sum_{t=1}^{\min(j,k)}f_{i,j}C_j^tC_{a_{i+1}-1}^{k-1}C_{s_i+1-j}^{k-t}
fi+1,j+ai+1−k−t=k=1∑ai+1t=1∑min(j,k)fi,jCjtCai+1−1k−1Csi+1−jk−t
k
k
k表示将第
i
i
i班的同学分成
k
k
k块,
t
t
t表示
k
k
k块中的
t
t
t块插入
j
j
j对相邻同学之间,
k
−
t
k-t
k−t块插在其他地方,注意枚举界限
t3 折半搜索,将长度为
n
/
2
n/2
n/2的路径方案求出来,然后合并
2021.8.21省选
t1 容易发现一棵树的答案为
∑
i
=
1
n
2
d
e
p
i
\sum_{i=1}^n2^{dep_i}
∑i=1n2depi,那么就可以对于每种标记维护一下该标记在
T
T
T树上的答案和,线段树维护即可
t2 考虑分治,实现函数
s
o
l
v
e
(
l
,
r
)
solve(l,r)
solve(l,r)解决
l
≤
x
1
≤
m
i
d
≤
x
2
≤
r
l\le x1\le mid\le x2\le r
l≤x1≤mid≤x2≤r的答案,考虑求出
f
i
,
j
f_{i,j}
fi,j表示点
(
i
,
j
)
(i,j)
(i,j)通过向右走和向下走能到达的
x
=
m
i
d
x=mid
x=mid直线上的点的集合,
g
i
,
j
g_{i,j}
gi,j表示点
(
i
,
j
)
(i,j)
(i,j)通过向左走和向上走能到达的
x
=
m
i
d
x=mid
x=mid直线上的点的集合,
(
x
1
,
y
1
)
(x1,y1)
(x1,y1)能到达
(
x
2
,
y
2
)
(x2,y2)
(x2,y2)当且仅当
f
x
1
,
y
1
f_{x1,y1}
fx1,y1和
g
x
2
,
y
2
g_{x2,y2}
gx2,y2有交集,
bitset
\text{bitset}
bitset优化即可做到
O
(
n
2
log
n
w
)
O(\frac{n^2\log n}{w})
O(wn2logn)
t3 当
u
u
u点被删时所造成的贡献为
u
u
u所在子树大小,如果此时
u
,
v
u,v
u,v联通则会有
1
1
1的贡献,令
p
u
,
v
p_{u,v}
pu,v表示
u
u
u被删时,
u
,
v
u,v
u,v联通的概率,答案即为
∑
i
=
1
n
∑
j
=
1
n
p
i
,
j
\sum_{i=1}^n\sum_{j=1}^np_{i,j}
∑i=1n∑j=1npi,j
考虑求出
p
u
,
v
p_{u,v}
pu,v,若
u
,
v
u,v
u,v在同一棵子树中,则两点间只有一条路径,由于
u
u
u被删时
u
,
v
u,v
u,v要联通,所以该路径上第一个被删的点必须是
u
u
u,概率为
1
l
e
n
\frac{1}{len}
len1,若
u
,
v
u,v
u,v不在同一棵子树中,意味着
u
,
v
u,v
u,v之间有两条路径,概率为
1
l
e
n
1
+
1
l
e
n
2
−
1
l
e
n
3
\frac{1}{len1}+\frac{1}{len2}-\frac{1}{len3}
len11+len21−len31,
l
e
n
3
len3
len3为两条路径必起来的大小
2021.8.23A组
t1 容易发现最优时肯定只会选
L
L
L个数,排序后对于没连续的
L
L
L个数求方差即可,震惊
d
o
u
b
l
e
double
double竟然比
l
o
n
g
l
o
n
g
long\ long
long long范围大
t2 枚举左端点,然后右端点向右扩张,每次扩张
g
c
d
gcd
gcd要么不变,要么变小,而且至少减少
g
c
d
/
2
gcd/2
gcd/2,每次扩张将
g
c
d
gcd
gcd相同的地方一次性扩完,贡献用快速幂计算,求区间
g
c
d
gcd
gcd用
s
t
st
st表优化
t3 直径性质:当两棵树用一条边连接起来时,新树的直径端点一定是原来两棵树的端点
对树求
d
f
n
dfn
dfn序,线段树结点维护
d
f
n
dfn
dfn序在所代表区间中最远的两个点,
O
(
n
log
2
n
)
O(n\log^2 n)
O(nlog2n)
t4 结论题,咕