日记
终于复活啦!!!
我们设最终 b 中 [1,mid] 的会被删完,a 中 [1,n−mid+1] 会被删完。
考虑何时这个 mid 合法。显然,如果有 i=1minn−mid+1ai>i=1minmidbi 时删的完。
考虑反证。显而易见的有当且仅当 i=1minn−mid+1ai<i=1minmidbi 非法。因为这样那个最小值死活都不可能被删了。
看到这个 mid 就该想到二分。但是在二分之前我们还得先证明以下单调性。也就是说当一个 mid 合法时 mid+1 也一定合法。我们发现当 mid 增加时,i=1minn−mid+1ai 单调不降,i=1minmidbi 单调不增。得证。
考虑有交换的情况。我们发现,对于 i∈[1,n−mid+1],如果有 ai<i=1minmidbi,我们可以通过交换把他扔出去,前提是外面有比 i=1minmidbi 大的。我们记录一个 cnt1 表示有多少个 ai<i=1minmidbi,cnt2 表示外面有多少个比他大的。那么当一个 mid 合法,当且仅当 cnt1≤1∧cnt2≥cnt1。于是直接二分最小的 mid,n−mid+1 就是答案。
我们考虑每个数。对于每个没出现的数,显然不会造成贡献。对于每个只出现 1 次的数,永远造成 1 的贡献。对于出现 2 次及以上的数,可以造成 ≤2 的贡献。但是经过一番手玩,我们发现这个 2 的上界似乎是一直可达的,于是这题就变成了一道构造题。
我们对于每个 ai↔bi 建一条无向边。确定位置的过程就是在给他定向。一条 u→v 的边就代表 ai=u,bi=v。于是我们就想把每个度 ≥2 的点都构造成至少一进一出的状态。
我们掏一颗 dfs 树出来,对于一条树边,他就是正向的。也就是说我从 u 走到 v 的这条树边定向就该是 u→v。反之就是反向的,应该是 v→u。我们发现这样构造的话,除了根节点的其他点都基本是合法的。如果根节点不合法,我们就翻转它的一颗子树里的所有边就是了。
我们钦定 A1≤A2。我们发现 A3 应当属于 [A2,A1+A2],因为 lcm(X1,X2)∈[X2,X1×X2]。于是我们就能判无解了。剩下的都是有解的情况。
- A3=A1+A2
我们显然想让 X3=X1×X2,我们构造一个 X1=6×10A1−1+1,X2=6×10A2−1 就可行了。 - A3≤A1+A2
构造一个 X1=10A1−1,X2=10A2−10A1+A2−A3−1 就行。
设 ci=biai。当所有 ci 相同时显然无解。
设我们找到了一对 i,j 满足 ci<cj。我们可以构造 xi=−(aj+bj),xj=ai+bi。其余都是 0。
为何正确?
自己推柿子去。
我们发现,对于两个不包含的区间,他们做出的贡献总是固定的。贡献可变的总是那些相互包含的。
设 i 包含了 j。那么我们想让 ansi 比 ansj 大,那么我们就从 i 向 j 建边。建完发现是个 DAG,我们直接拓扑排序。至于字典序最小,用个大根堆就是了。
为啥不用小根堆呢?
我们发现,“某几条边界上不存在点”的情况是好求的。因为只有 4 条边,我们直接暴力容斥。枚举删除哪几条边就是了。
事实证明:有些时候用“类反演”的思维理解容斥好一点,有些时候就是真容斥。
这题更是重量级。
我们口胡一下,发现只有 gcd(ai,m) 的倍数的点会被选。你以为这就可以开始容斥了吗?其实不然。
我们发现 gcd(ai,m) 一定是 m 的因数(这不废话吗),而 [1,109] 里因数最多的也就 1500 多个因数。我们枚举每个因数,对于第 i 个因数,我们记录一个 vali 表示它做出贡献的系数。每当我们计算完一个因数的贡献,我们就把它的倍数的 val 减去一个 vali。
根本就不是容斥,你被骗啦!
今天似乎是有点颓废的,但是却做了这么多题。今天除了补好题还有数论,我还水了两道网络流。
今天到底颓不颓呢?