1 条题解

  • 0
    @ 2025-12-11 4:19:51

    题解:密码特征值与X位置的映射

    问题转化

    已知n=2k+1n=2k+1个位置排成环,其中kk个位置是A(集合PP),kk个位置是B,1个位置是X。

    定义:从X顺时针出发,到某个A时,若途中A的个数严格大于B的个数,则称该A为“强的”。特征值=强的A的个数。

    给定A的位置(即集合PP),有k+1k+1种放置X的位置(对应k+1k+1个空位),特征值恰好取遍0,1,,k0,1,\dots,k

    需要根据特征值反推X的位置。

    关键概念

    1. 序列表示

    将环从X断开,按顺时针展开为长度为2k2k的序列(不含X)。
    令A对应+1+1,B对应1-1,得到一个长度为2k2k的序列s1,s2,,s2ks_1,s_2,\dots,s_{2k},其中+1+1kk个,1-1kk个。

    2. 前缀和与强的A

    设前缀和prei=s1+s2++sipre_i = s_1 + s_2 + \dots + s_i

    从X出发顺时针到第jj个A(按遇到顺序)时,设该A在序列中的位置为tt,则途中A的个数严格多于B的个数 ⇔ 到达该A时的前缀和pret>0pre_t > 0

    因此,强的A的个数就是所有A位置中满足pret>0pre_t > 0的个数。

    3. 不同断点对应不同特征值

    当X的位置移动时,序列循环移位。设原序列(固定某个参考X)为s1,,s2ks_1,\dots,s_{2k},前缀和为preipre_i

    若X顺时针移动dd步(即原序列向右循环移位dd),则新序列为sd+1,,s2k,s1,,sds_{d+1},\dots,s_{2k},s_1,\dots,s_d

    新前缀和prei=pred+ipredpre'_i = pre_{d+i} - pre_d(对i2kdi \le 2k-d)或prei=prei(2kd)+(pre2kpred)pre'_i = pre_{i-(2k-d)} + (pre_{2k} - pre_d)(对i>2kdi > 2k-d)。

    但注意pre2k=0pre_{2k}=0(因为+1+11-1数量相等),所以prei=pre(d+i)mod2kpredpre'_i = pre_{(d+i)\bmod 2k} - pre_d(模2k2k下标,且pre0=0pre_0=0)。

    因此,新序列中位置tt的符号为+1+1时,条件是pre(d+t)mod2kpred>0pre_{(d+t)\bmod 2k} - pre_d > 0

    4. 转化为找第S大的断点

    问题变为:给定pre1,,pre2kpre_1,\dots,pre_{2k},求一个偏移dd0d<2k0\le d < 2k,且dd对应一个B或A的位置?实际上dd对应原X后的位置索引),使得满足pre(d+t)mod2kpred>0pre_{(d+t)\bmod 2k} - pre_d > 0tt个数(其中s(d+t)mod2k=+1s_{(d+t)\bmod 2k}=+1)等于SS

    由于ddk+1k+1个特定值(对应X在某个非A位置?不,X可以在任何位置,但给定A的位置时,X只能放在非A位置,有k+1k+1个空位)。

    实际上,dd对应X在原序列中的“前一个位置”索引。设原序列s1,,s2ks_1,\dots,s_{2k}对应某个参考X(比如放在位置1之前)。则X实际在位置ii之前(i=1,,2k+1i=1,\dots,2k+1)对应偏移d=i1d=i-1(模2k2k),但需保证ii不是A的位置(因为X不能与A重叠)。

    5. 特征值0对应X的位置

    特征值0表示没有强的A,即对所有A位置ttpre(d+t)mod2kpred0pre_{(d+t)\bmod 2k} - pre_d \le 0

    由于prepre是整数且变化量为±1,这等价于pre(d+t)mod2kpredpre_{(d+t)\bmod 2k} \le pre_d对所有A位置tt成立。

    这要求predpre_dprepre在所有A位置索引上的最大值?不,是predmaxtApretpre_d \ge \max_{t \in A} pre_t?但prepre可能重复。

    实际上,令M=maxtApretM = \max_{t \in A} pre_t,需要predMpre_d \ge M?但若pred=Mpre_d = M且某个A位置tt满足pret=Mpre_t = M,则差为0,不满足严格大于0,所以该A不强。因此特征值0的条件是:predmaxtApretpre_d \ge \max_{t \in A} pre_t,且取等时该A不算强。

    但更精确地:对所有A位置ttpre(d+t)mod2kpredpre_{(d+t)\bmod 2k} \le pre_d

    由于序列循环,可重新标号使X在位置0(即偏移d=0d=0),那么pret0pre_t \le 0对所有A位置tt成立。

    因此问题转化为:找到一个循环移位,使得所有A位置的前缀和0\le 0

    6. 已知结论

    由题目结论,特征值SS与X的位置一一对应,且特征值SS等于“从X顺时针出发,第一次遇到前缀和达到某个值的次数”等。

    实际上,若将prepre值看作高度,从X出发(高度为predpre_d),顺时针走,遇到A时检查当前高度是否大于出发高度。强的A的个数就是高度严格大于出发高度的A的个数。

    因此,将所有位置按prepre值排序,特征值SS对应选择第S+1S+1高的出发高度?但需考虑A的位置。

    7. 特征值S的X位置

    更系统的方法: 定义数组pre[0..2k]pre[0..2k]pre[0]=0pre[0]=0pre[i]=pre[i1]+sipre[i]=pre[i-1]+s_i,其中si=+1s_i=+1如果位置ii是A,否则1-1

    环上位置从1到2k+12k+1,X放在位置pospos1pos2k+11\le pos\le 2k+1)时,对应断点在pos1pos-1(模2k2k),即偏移d=pos1d = pos-1

    h=predh = pre_d(出发高度)。

    强的A的个数 = #{ tAt \in A | pret>hpre_t > h }(在循环意义下,pretpre_ttt位置的前缀和,注意tt索引可能大于dd需调整)。

    因为循环移位后,位置tt的新前缀和为prethpre_t - h(若t>dt>d)或pret+pre2kh=prethpre_t + pre_{2k} - h = pre_t - h(因为pre2k=0pre_{2k}=0)。所以确实就是pret>hpre_t > h的A的个数。

    因此,特征值SS对应选择hh使得恰好有SS个A位置满足pret>hpre_t > h

    8. 具体算法

    预处理:

    • 给定A的位置集合PP(大小为kk)。
    • 构造序列s[1..2k]s[1..2k],对应位置1..2k1..2k为A(+1)或B(-1),位置2k+12k+1留给X?注意环上共2k+12k+1个位置,但我们构造序列时先固定X在位置2k+12k+1,则序列s1..s2ks_1..s_{2k}对应位置1..2k1..2k的值。
    • 计算前缀和pre[0..2k]pre[0..2k]pre[0]=0pre[0]=0pre[i]=pre[i1]+sipre[i]=pre[i-1]+s_i
    • 记录所有A位置(在1..2k1..2k中)的prepre值,记为集合HAH_A
    • HAH_A排序。

    对于特征值SS: 我们需要hh使得#{ xHAx>hx \in H_A | x > h } = SS。 由于SS从0到kkhh应取HAH_A中第kSk-S大的值?不,#{ x>hx > h } = SS ⇒ 有SS个大于hhkSk-S个小于等于hh。所以hhHAH_A中第kSk-S小的值?不,若hh等于某个HAH_A值,则相等的不算大于,所以hh应介于HAH_A中第kSk-S大和第kS+1k-S+1大之间?但hh必须是某个predpre_d值(d=0..2kd=0..2k)。

    实际上,h=predh = pre_ddd是某个位置索引(0..2k)。我们需要#{ tApret>predt \in A | pre_t > pre_d } = SS

    因此,对每个dd(0..2k),计算c(d)=c(d) = #{ tApret>predt \in A | pre_t > pre_d }。 则c(d)c(d)取遍0..k,且一一对应。

    我们需要:

    • 特征值0:c(d)=0c(d)=0predmaxtApretpre_d \ge \max_{t\in A} pre_t
    • 特征值S:c(d)=Sc(d)=Spredpre_d是使得恰好SSpretpre_t大于它的值。

    因此,将所有predpre_dd=0..2kd=0..2k)排序,并与HAH_A比较,即可得到每个c(d)c(d)

    9. 位置映射

    dd对应X在位置d+1d+1(若d<2kd<2k)或位置2k+12k+1(若d=2kd=2k?注意dd范围0..2k-1对应位置1..2k,d=2kd=2k对应位置2k+12k+1?但pre[2k]=0pre[2k]=0,且位置2k+12k+1是X)。

    但注意:dd是序列索引(0..2k-1)对应位置d+1d+1是X?不,若dd是前缀和索引,则dd对应在位置dd之后放X(即X在位置d+1d+1,环上模2k+12k+1)。

    更准确:设位置1..2k+1,序列s1..s2ks_1..s_{2k}对应位置1..2k,位置2k+12k+1是X(参考)。那么pre[i]pre[i]对应位置ii(i=1..2k)的前缀和。X放在位置pospos时,相当于将环旋转使pospos成为新起点,则新序列的前缀和是原prepre减去pre[pos1]pre[pos-1](模意义)。因此h=pre[pos1]h = pre[pos-1](若pos=2k+1pos=2k+1,则h=pre[2k]=0h=pre[2k]=0)。

    因此,d=pos1d = pos-1d=0..2kd=0..2kd=2kd=2k对应pos=2k+1pos=2k+1)。

    10. 答案计算步骤

    1. 给定A的位置集合PP(大小为kk)。

    2. 构造数组s[1..2k]s[1..2k]:对i=1..2ki=1..2k,若iPi \in Ps[i]=1s[i]=1,否则s[i]=1s[i]=-1

    3. 计算pre[0..2k]pre[0..2k]pre[0]=0pre[0]=0pre[i]=pre[i1]+s[i]pre[i]=pre[i-1]+s[i]i=1..2ki=1..2k)。

    4. 收集所有pre[t]pre[t]tPt \in P)到数组HAH_A,排序。

    5. d=0..2kd=0..2k,计算c(d)=c(d) = #{ xHAx>pre[d]x \in H_A | x > pre[d] }。

      • 可通过排序所有pre[d]pre[d]并与HAH_A比较得到。
    6. 建立映射f:c(d)pos=d+1f: c(d) \rightarrow pos = d+1(若d<2kd<2k)或pos=2k+1pos=2k+1(若d=2kd=2k)。

      • 注意:pospos不能是A的位置,需检查posPpos \notin P。但d=2kd=2k对应pos=2k+1pos=2k+1肯定不在PP(因为P{1..2k}P \subseteq \{1..2k\})。对于d<2kd<2k,若pos=d+1Ppos=d+1 \in P,则这个dd不可行(因为X不能放在A上)。所以实际上dd只能取pos1pos-1posPpos \notin P
      • 因此需要过滤:dd满足d+1Pd+1 \notin P(且d2kd \le 2k)。
      • d=2kd=2kpos=2k+1pos=2k+1自动满足。
    7. 对于特征值S:

      • 第一问:S=0S=0,找c(d)=0c(d)=0d+1Pd+1 \notin Ppos=d+1pos=d+1
      • 第二问:SS,找c(d)=Sc(d)=Sd+1Pd+1 \notin Ppos=d+1pos=d+1
      • 第三问:给定B的位置(即PP是B的位置),则A的位置是补集。同样计算,只需将s[i]s[i]符号取反?不,只需将HAH_A改为A位置的prepre值(A位置是PP的补集)。

    11. 时间复杂度

    • 构造prepreO(k)O(k)
    • 排序:O(klogk)O(k \log k)
    • 映射:O(k)O(k) 总复杂度O(klogk)O(k \log k),可过k107k\le 10^7(需注意内存和常数)。

    12. 具体实现

    • 用数组存储prepre和位置信息。
    • 用计数排序或快速排序。
    • 注意kk很大,避免递归爆栈。

    13. 第三问转换

    给定B的位置集合PBP_B(大小kk),则A的位置是补集PA={1..2k}PBP_A = \{1..2k\} \setminus P_B。 算法同上,只需将HAH_A改为PAP_Aprepre值集合。

    14. 最终输出

    对每个询问,输出对应的pospos即可。

    • 1

    信息

    ID
    6074
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者