Problem
Description
You are given a binary string S of length N.
Construct a directed graph based on this sequence: for any pair of indices (i,j), if Si=0, Sj=1, and i<j, add a directed edge from node i to node j.
这个图有很多性质:
- VC:前缀 0 + 后缀 1,这个数量的最小值就是 MVC
- IS:前缀 1 + 后缀 0
Initially, each node i has a score of Wi, represented by the array W=[W1,W2,…,WN]. You can perform the following two types of operations any number of times:
- Choose a node i satisfying Si=0: Node i gives exactly 1 point to each of its adjacent nodes. As a result, the score of node i decreases by its out-degree, and the score of each of its out-neighbors increases by 1.
- Choose a node j satisfying Sj=1: Node j takes exactly 1 point from each of its adjacent nodes. As a result, the score of node j increases by its in-degree, and the score of each of its in-neighbors decreases by 1.
In other words, the flow of points follows the direction of the edges in the graph.
Determine whether there exists a sequence of operations such that ultimately every node has a score of exactly 0 (i.e., Wi=0 holds for all i).
Constraints
- 2≤N≤106
- −109≤Wi≤109
给定一个长度为 N 的 01 字符串 S。
根据该序列构造一个有向图:对于任意 (i,j),如果 Si=0、Sj=1,且 i<j,则添加一条从 i 指向 j 的有向边。
初始时,每个节点 i 都有一个分数值 Wi,由数组 W=[W1,W2,…,WN] 表示。你可以执行以下两种操作任意次:
- 选择一个满足 Si=0 的节点 i:节点 i 向其每个出边邻居各给予 1 分。
- 选择一个满足 Sj=1 的节点 j:节点 j 从其每个入边邻居各拿取 1 分。
换言之,分数流向就是图的箭头流向。
判断是否存在一种操作序列,使得最终每个节点的分数都恰好为 0(即对于所有 i,均满足 Wi=0)。
Solution
特判:
- 在第一个 0 之前的所有 1,初始分数 Wi 必须为 0。
- 在最后一个 1 之后的所有 0,初始分数 Wi 必须为 0。
- 总和 ∑Wi 必须等于 0。
下面不妨设 S1=0,SN=1。
设 Vi 为节点 i (Si=0) 的操作次数,−Vj 为节点 j (Sj=1) 的操作次数。边 i→j 上的流量为 Vi−Vj。每个节点的流量之和满足:
- 若 Sk=0:Wk=∑j>k,Sj=1(Vk−Vj)
- 若 Sk=1:Wk=∑i<k,Si=0(Vk−Vi)
设 fk=∑i=1kWi 为 W 的前缀和。
设 c0(k) 为前缀 S[1…k] 中 0 的个数,c1(k) 为后缀 S[k+1…N] 中 1 的个数。
将 W 从 1 累加到 k,所有内部的流量会相互抵消,只剩下跨越边界 k 的流量。我们得到:
fk=i=1∑kWi=c1(k)i⩽k,Si=0∑Vi−c0(k)j>k,Sj=1∑Vj
不妨假设 v1=0(因为 Vk 的绝对大小并不重要,整体加上一个常数 C 并不会改变流量 Vi−Vj,所以我们可以从左到右递推构造出一个相对数列 vk),并设 ak 为直到下标 k 为止所有 0 对应的 vi 之和 (ak=∑i≤k,Si=0vi)。
通过代数变形,我们可以严格从左到右求解 vk:
如果 Sk=0:
vk=c0(k−1)c1(k)c1(k)ak−1+c0(k−1)Wk−fk−1
ak=ak−1+vk
如果 Sk=1:
ak=ak−1
vk=c0(k)Wk+ak−1
如果在任何一步计算中,分子 不能被分母整除,说明 vk 不是整数(无法用离散次数的操作达成),直接输出 NO。
即使我们求出了整数序列 vk,我们还必须保证操作次数是非负的(xi≥0,yj≥0)。这隐含地要求每条边上的流量必须满足 Vi−Vj≥0。
因为我们已经证明了 Vi−Vj=vi−vj,所以我们必须保证对于所有的 Si=0 和所有的 Sj=1,都有 vi−vj≥0。
这等价于检查:
i:Si=0minvi≥j:Sj=1maxvj
如果该不等式成立,输出 YES;否则输出 NO。