2019-8-5
T1:炮艇大赛之正式赛
有一个环,长度为L,上面有n个点,第i个点坐标为
d
i
d_i
di,速度为
v
i
v_i
vi,可以为负,当i,j两点相撞,编号较小的点消失,问什么时候大赛结束。
所有数据均为整数
1
≤
n
≤
1
0
5
1\leq n \leq 10^5
1≤n≤105
1
≤
L
≤
1
0
9
1\leq L\leq 10^9
1≤L≤109
0
≤
d
i
<
L
0\leq d_i <L
0≤di<L
∣
v
i
∣
≤
1
0
9
|v_i|\leq 10^9
∣vi∣≤109
每次维护相邻两个点的相撞时间,加一个堆维护最小值即可
删除一个点时会产生一对新的相邻的点 也更新一下
T2:匹配
n个点的树,问有多少种删除边的方式,使得剩下的图的最大匹配为m的倍数
1
≤
n
≤
55
∗
1
0
4
1\leq n \leq 55*10^4
1≤n≤55∗104
考虑树形dp,令
f
u
,
0
,
i
f_{u,0,i}
fu,0,i,表示u的子树中有多少种删除边的方式,使得最大匹配数模m的值为i,且u点选与不选都可以达到该最大匹配
1的意义恰好相反
递推式子不难推
然后一次转移复杂度为
m
i
n
(
s
i
z
1
,
m
)
∗
m
i
n
(
s
i
z
2
,
m
)
min(siz1,m)*min(siz2,m)
min(siz1,m)∗min(siz2,m)
以下证明复杂度会是nm
首先形象理解:相当于一开始有n个堆,每堆一个点,每次选两个堆合并,会产生一定代价
siz1,siz2两个都大于m,at most
⌊
n
m
⌋
\left \lfloor \frac{n}{m} \right \rfloor
⌊mn⌋次
siz1,siz2一个大于m,将m赋值于较小集合上的每个点,每个点最多被赋值一次
都不大于m,同样是赋值,证一下就完了 赋值超过m,那么其点所在的点集合也会大于m
于是复杂度是nm
T3:
题意大概是有个序列,长度n,不停修改其中一个数
修改中查询l,r
问
∑
i
=
l
r
m
i
n
(
a
l
,
.
.
.
,
a
i
)
\sum_{i=l}^{r}min(a_l,...,a_i)
∑i=lrmin(al,...,ai)
线段树搞一下就好了
最后,博主正在恢复智商中
T2这种结论是不可能想出来的
了解一下李超线段树合并,有惊喜
大概可以通过启发式的方式做到
n
l
o
g
2
n
nlog_2n
nlog2n
2019-8-6
学了一下二进制分组,还是很神奇的
2019-8-7
T2:n个二元组,找到
⌊
n
2
⌋
\left \lfloor \frac{n}{2} \right \rfloor
⌊2n⌋+1个,满足其中每个个元的总和大于总的每个元的一半
设序列为
a
1
,
a
2
,
.
.
.
,
a
n
a_1,a_2,...,a_n
a1,a2,...,an
b
1
,
b
2
,
.
.
.
b
n
b_1,b_2,...b_n
b1,b2,...bn
按a从小到大排序,两个相邻的b取最大的即可,最后一组根据n的奇偶性讨论
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
#define Maxn 100010
struct Data{
int a,b,id;
bool operator <(const Data &z)const{return a<z.a;}
}data[Maxn];
bool sta[Maxn];
inline void rd(int &x){
x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
}
int main(){
rd(n);
for(register int i=1;i<=n;++i)rd(data[i].a),data[i].id=i;
for(register int i=1;i<=n;++i)rd(data[i].b);
sort(data+1,data+n+1);
for(register int i=1;i<=n-1;i+=2){
if(data[i].b>data[i+1].b)sta[i]=true;
else sta[i+1]=true;
}
if(n&1)sta[n]=true;
else{
sta[n]=sta[n-1]=true;
}
printf("%d\n",n/2+1);
for(register int i=1;i<=n;++i)
if(sta[i])printf("%d ",data[i].id);
return 0;
}
T3中,有根树不能轻易makeroot,因为一个节点的更新需要所有子树节点的翻转,更新不可能延迟
2019-8-9
代码能力大赛,还是要提高打代码速度
2019-8-12
再次数据结构大赛
因为代码能力被打爆
注意trie树是可以push_down的
2019-8-13
怎么代码老是写挂啊
2019-8-15
有一道有趣的题
四个点,编号1~4
其中,(1,2)(2,3)(3,4)(4,1)均有一条正权值的边,记为
d
1
,
d
2
,
d
3
,
d
4
d_1,d_2,d_3,d_4
d1,d2,d3,d4
从2出发,找到一条路径(可以不简单),满足长度大于等于K,并且该长度最小。
求长度。
K
≤
1
0
18
,
d
≤
3
∗
1
0
4
K\leq 10^{18},d\leq 3*10^4
K≤1018,d≤3∗104
一开始往一笔画上想了,然后推出了生成函数,然后自闭了…
不妨设
W
=
m
i
n
(
2
∗
d
1
,
2
∗
d
2
)
W=min(2*d1,2*d2)
W=min(2∗d1,2∗d2)
于是如果有长度为k的路径,那么也有长度为
k
+
W
k+W
k+W的路
这启式我们可以按模W的余数进行分类
设
d
i
s
i
,
j
dis_{i,j}
disi,j为到达i时模W余j时的最小值
对每个模数分类讨论即可
复习一下tarjan(无向图中)
一定要注意,无向图用tarjan实际上是建出dfs树,那么对于非树边一定是返祖边,然后割点(注意判根节点)与割边的算法就好理解了
2019-8-16
欢乐被打爆
这个t2…不想讲了
t3还是蛮有趣的
题意:一个长度为n的序列,Q次询问和操作
询问l,r的子区间有多少个不同的子序列
将l,r区间的值翻转(值为0,1)
n
,
Q
≤
1
0
5
n,Q\leq 10^5
n,Q≤105
解法:先喜闻乐见地推出dp式子
当
a
i
=
1
a_i=1
ai=1,
d
p
i
,
0
=
d
p
i
−
1
,
0
+
d
p
i
−
1
,
1
+
1
,
d
p
i
,
1
=
d
p
i
−
1
,
1
dp_{i,0}=dp_{i-1,0}+dp_{i-1,1}+1,dp_{i,1}=dp_{i-1,1}
dpi,0=dpi−1,0+dpi−1,1+1,dpi,1=dpi−1,1
a
i
=
0
a_i=0
ai=0同理
那么这就会是一个矩阵乘法
可是,你会悲催地发现,怎么处理翻转操作啊
有个神奇的结论,翻转的矩阵乘积为原来乘积交换第1,2行,第1,2列交换
猜结论是不可能猜出来的,所以我们还是要证明一下的QWQ
首先我们构造一个矩阵E
这个矩阵近似单位矩阵
但是它第i行数值为1的位置在j
第j行数值为1的位置在i
E
∗
A
E*A
E∗A表示交换A的第i,j行
A
∗
E
A*E
A∗E表示交换A的第i,j列
且
E
∗
E
E*E
E∗E是单位矩阵
于是证明显而易见了
2018-8-18
T1Travel in Sugar Country
N个站,在一条线上,K排列,求距离和为m的倍数的方案数
n
≤
100
,
m
≤
30
,
K
≤
50
n\leq 100,m\leq 30,K\leq 50
n≤100,m≤30,K≤50
其实,这种路径问题,很多时候是可以从插头dp的角度进行考虑的
对每段线段加左箭头,右箭头,最终使起点和终点联通
过程中使左右箭头不能联通
故DP有6维:现在在第i个城市(N个状态),前i个城市的贡献(M个状态),前i个城市选了几个商店(K个状态),经过i->i+1这条边的路径数量(根据这个数量,可以计算出向右的和向左的数量)(K个状态),前i个城市是否有起点(2个状态),前i个城市是否有终点(2个状态)
T3:Ascending Tree
给你一棵有根树。每个节点有个权值。如果你花费1块钱,你就可以对某个节点的权值加1或减1。
现在,你的目标是用最小的花费,使得:对于这棵树上的每一个顶点,它的儿子的权值严格小于它本身的权值。
n
⩽
5
∗
1
0
5
,
∣
c
i
∣
⩽
1
0
9
n\leqslant 5*10^5,|c_i|\leqslant 10^9
n⩽5∗105,∣ci∣⩽109
左偏树
可以看到其中Baltic 2004
即对序列问题的一种解法
扩展到树上,不过我也不知道怎么证
维护联通快的中位数
若不满足大于等于条件,取最大的,合并
至这里于用左偏树维护中位数的方式
是因为联通快A的中位数原本大于等于联通块B的中位数
A加入一个数C后中位数小于了B的
那么这种维护方式自然是可行的QWQ
T2:给一个n个点的凸包,求与坐标轴平行的长方形的面积最大值及其位置。
n
⩽
1
0
5
n\leqslant10^5
n⩽105
猜一猜这题的复杂度
实际上,除去读入外,只要
l
o
g
n
3
logn^3
logn3
令
s
(
x
,
w
)
s(x,w)
s(x,w)为x轴为x时,长方形长为w时的面积最大值
然后你会发现,以x为自变量,这个函数是凸的
于是,令KaTeX parse error: Expected 'EOF', got '}' at position 18: …w)={max(s(x,w)}}̲
然后,这个函数也是凸的
求x=x0与凸包的交点二分求…
然后就解决了
2018-8-27
集训结束了!
学还是学了不少东西的!