假算法轻取 96pts。
T1:
给定一个\(n\)个结点\(m\)条边的简单无向图,结点编号\(1\sim n\)。你需要构造一个结点编号的排列\(v_1,v_2,\cdots,v_n\),满足
- \(v_1=1\);
- 对\(1< i < n\),至多一个\(i\)满足要求:点对\((v_i,v_{i+1})\)和\((v_i,v_{i-1})\)中,一对之间有边直接相连,另一对没有。即对排列中非两端的结点,至多一个和排列中的两侧邻点中恰一个有边直接连接。
请输出一个满足条件的排列。
"有 \(n\) 个人戴了黑白帽子,每人不知道他的帽子是什么色的,怎么排成黑白分明的队伍?"
让每个人插入到当前序列的黑白交界处即可。
本题一样,让每个结点判断与交界处是否有边来决定去左边还是右边。
T2:
数轴上有 \(n\)个有编号的点,其中在时刻\(t=0\)时\(i\)号位于\(x_i\) ,并具有初速度\(v_i\in \{1,-1\}\)(每单位时间的坐标变化)。保证初始位置各不相同。
之后所有点开始运动,如果在时刻\(t\),编号为\(x,y\)的两个点位置重合,且\(v_x=1,v_y=-1\),则碰撞在了一起,这时记录一个碰撞事件\((t,x,y)\),并令\(v_x,v_y\)值互换。如果同时出现多个碰撞事件,可以任意顺序各自独立的结算。
可以发现会出现的碰撞事件\((t,x,y)\)是有限的,请找出字典序排序后的第\(l\sim r\)个事件的\(x,y\),保证存在\(r\)个事件。
\(\dagger\) 多元组\((t,x,y)\)的字典序指先按第一个元素\(t\)从小到大排序,\(t\)相同的按\(x\)从小到大,\(x\)也相同的按\(y\)从小到大。
经典转化:碰撞并不是回头了,而是都继续往前走。
先把所有点按坐标排序。二分 + 双指针可以求出字典序 \(l\sim r\) 的事件所属的时间区间 \([tl,tr]\)。
容易发现碰撞对象只可能是相邻两个球。同时 \(i,i+1\) 的第一次碰撞时间等于 \(\le i\) 第一颗右球和 \(\ge i+1\) 的第一颗左球相遇的时间(就是碰撞继续走),第二次碰撞时间是 \(\le i\) 的第二颗右球和 \(\ge i\) 的第二颗左球 ……
我们要找到(第 \(i\) 颗左球,第 \(i\) 颗右球)这些对里,发生时间在 \([tl,tr]\) 里的。
可以预处理 \(lst[i],nxt[i]\) 表示 \(i\) 的上一颗右球、下一颗左球。可以暴力向左右跳。复杂度平方。
因为 \(>tr\) 可以直接 break,瓶颈在于经过了很多发生时间 \(<tl\) 的碰撞。
如何快速找到第一次发生时间 \(\ge tl\) 的碰撞?使用 ST 表加速即可。
坑点:最终可能有开头的几个时间字典序 \(<l\),因为二分可能会留下一点。
T3:
求构造满足如下条件的\(n\)长度整数序列\(a_1,a_2,\cdots,a_n\)的方案数
- 所有整数的取值范围为\(1\sim m\);
- 对\(1\le i < n\),以下两个条件至少一个成立:
- \(a_i\le a_{i+1}\);
- \((a_i\mod a_{i+1}) > 0\)。
答案对998244353取模。两个方案不同,当且仅当存在至少一个位置,使两个序列中该位置的数不相等。
\(n,m\le 10^5\)。
妙题。对容斥集合直接 DP。
注意到不满足的条件很苛刻。如果 \(a_i,a_{i+1}\) 是不满足的,必须 \(a_{i+1}\) 是 \(a_i\) 的真因数。而连续的真因数 \(\log n\) 次就变成 \(1\)。
因此可以求出 \(c[i][j]\) 为:长度 \(i\) 的序列以 \(j\) 结尾,任意相邻位置不合法的方案数。\(i\le 20\) 可以递推。令 \(sc[i]=\sum c[i][]\)。
既然不合法的情况这么少见,可以考虑容斥。怎么容?平时是 "至少 \(0\) 个不满足" - "至少 \(1\) 个不满足" + "至少 \(2\) 个不满足" - ……,容易发现偶数加奇数减。
我们直接 \(dp[i][0/1]\) 表示填前 \(i\) 个数,使得有偶数/奇数个位置不满足的方案数。
如何转移?枚举 \(i\sim i-j\) 是一段连续不合法段,根据上面的观察有 \(j\le 20\)。
此时就已经有了 \(j\) 个不合法,方案数是 \(sc[j]\),如果要贡献到 \(dp[i][0]\) 里,后面要有 \(j\bmod 2\) 的位置不满足;否则需要 \(1-j\bmod 2\) 的位置不满足。
dp[i][0] += sc[j + 1] * dp[i - j - 1][j % 2] % MOD;
dp[i][0] %= MOD;
dp[i][1] += sc[j + 1] * dp[i - j - 1][1 - j % 2] % MOD;
dp[i][1] %= MOD;
复杂度 \(O(m\log m+n\log m)\)。
标签:11,结点,le,NOIP,碰撞,2024,满足,sim,dp From: https://www.cnblogs.com/FLY-lai/p/18574225