2019暑假比赛笔记

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 1n105
1 ≤ L ≤ 1 0 9 1\leq L\leq 10^9 1L109
0 ≤ d i &lt; L 0\leq d_i &lt;L 0di<L
∣ v i ∣ ≤ 1 0 9 |v_i|\leq 10^9 vi109
每次维护相邻两个点的相撞时间,加一个堆维护最小值即可
删除一个点时会产生一对新的相邻的点 也更新一下
T2:匹配
n个点的树,问有多少种删除边的方式,使得剩下的图的最大匹配为m的倍数
1 ≤ n ≤ 55 ∗ 1 0 4 1\leq n \leq 55*10^4 1n55104
考虑树形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 K1018,d3104
一开始往一笔画上想了,然后推出了生成函数,然后自闭了…
不妨设 W = m i n ( 2 ∗ d 1 , 2 ∗ d 2 ) W=min(2*d1,2*d2) W=min(2d1,2d2)
于是如果有长度为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,Q105
解法:先喜闻乐见地推出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=dpi1,0+dpi1,1+1,dpi,1=dpi1,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 EA表示交换A的第i,j行
A ∗ E A*E AE表示交换A的第i,j列

E ∗ E E*E EE是单位矩阵
于是证明显而易见了
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 n100,m30,K50
其实,这种路径问题,很多时候是可以从插头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 n5105,ci109
左偏树
可以看到其中Baltic 2004
即对序列问题的一种解法
扩展到树上,不过我也不知道怎么证
维护联通快的中位数
若不满足大于等于条件,取最大的,合并
至这里于用左偏树维护中位数的方式
是因为联通快A的中位数原本大于等于联通块B的中位数
A加入一个数C后中位数小于了B的
那么这种维护方式自然是可行的QWQ
T2:给一个n个点的凸包,求与坐标轴平行的长方形的面积最大值及其位置。
n ⩽ 1 0 5 n\leqslant10^5 n105
猜一猜这题的复杂度
实际上,除去读入外,只要 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
集训结束了!
学还是学了不少东西的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值