1 条题解

  • 0
    @ 2025-8-24 22:10:09

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar _rqy
    **

    搬运于2025-08-24 22:10:09,当前版本为作者最后更新于2019-11-06 01:31:21,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    首先既然胜利条件是“每个数都是一个给定质数 P 的倍数”,那么当然我们可以时时刻刻把 SSPP 取模。

    那么我们考虑最快可以在多少步内胜利:反过来考虑,什么样的序列可以在零步内胜利?当然是全 0 序列。

    什么样的序列可以在一步内胜利?假设我们给出了 TT,使得无论 Bob 怎么操作都会变成全 0,那么说明对任意的 i,ji,j 都有 Si+Tj=0S_i+T_j=0(加法和等于都是在 modP\bmod P 意义下的,下同)容易发现这只在 SiS_i 全相等时可能发生;因此一步内胜利等价于 SiS_i 全相等。

    什么样的序列可以在两步内胜利?那相当于说无论 Bob 怎么操作,序列都会变成全相等的序列。也就是说我们给出 TT 之后,Bob 任选一个 xxSS' 的相邻两项都会相等,即 Si+Ti+x=Si+1+Ti+1+xS_i+T_{i+x}=S_{i+1}+T_{i+1+x},也就是说 Si+1Si=Ti+x+1Ti+xS_{i+1}-S_i=T_{i+x+1}-T_{i+x}。既然 xx 是任意的,i+xi+x 也就可以任取,也就是说对任何 i,ji,j 都有 Si+1Si=Tj+1TjS_{i+1}-S_i=T_{j+1}-T_j。这样的话,不难看出所有的 Si+1SiS_{i+1}-S_i 都相等,也就是说差分之后会全部相等。


    我们发现,一步之内可以胜利当且仅当 SiS_i 全都相等,即 SS 差分一次之后会变成全零序列;两次之后可以胜利当且仅当 SS 差分两次会变成全零序列。那么可不可以推广出这样的结论:kk 次之后可以胜利当且仅当 SS 差分 kk 次会变成全零序列?

    答案是肯定的。如果 SiS_i 差分 kk 次后会变成全 00,那么也就是说它差分 k1k-1 次之后会变成每一项都相同的序列,设这个相同项为 aa。我们取 Ti=SiT_i=-S_i,那么显然 TT 差分 k1k-1 次就会变成每一项都是 a-a 的序列。那么无论 Bob 怎么移动这个 TT 再把它和 SS 加起来,得到的序列差分 k1k-1 次之后都会变成全为 a+(a)=0a+(-a)=0 的序列。

    这样我们就证明了“SS 差分 kk 次后会变成全 00 序列”    \implieskk 步之后可以获胜”。另一个方向(从右边推到左边)也可以类似归纳证明,即若 kk 步后可以获胜那么 SS 差分 kk 次必须是全 00 序列。


    这样问题就转化成了:求最小的 kk 使得 SS 差分 kk 次后会变成全 00 序列。为了统一说法,下面认为差分一次后 Si=SiSi+1S'_i=S_i-S_{i+1}

    为了下面方便,我们先说明一个事实:如果对 SS 差分 pkp^k 次,那么得到的序列 Si=SiSi+pkS'_i=S_i-S_{i+p^k}。这是因为差分 tt 次后

    Si=j=0t(1)j(tj)Si+jS'_i=\sum_{j=0}^t(-1)^j\binom{t}{j}S_{i+j}

    代入 t=pkt=p^k 后可以发现,对于 0<j<pk0<j<p^k(pkj)=pk!j!(pkj)!\binom{p^k}{j}=\frac{p^k!}{j!(p^k-j)!} 里分子上 pp 的次数大于分母上 jj 的次数,因此 (pkj)0(modp)\binom{p^k}{j}\equiv0\pmod p。于是差分 pkp_k 次后

    Si=Si+(1)pkSi+pk=SiSi+pkS'_i=S_i+(-1)^{p^k}S_{i+p^k}=S_i-S_{i+p^k}

    (注意虽然 p=2p=2(1)pk=1(-1)^{p^k}=1,但是 mod2\bmod 2 意义下 1=11=-1

    那么考虑首先找到一个最小的 kk,使得 pkp^k 次差分后得到全 0,也就说对于任意的 ii 都有 Si=Si+pkS_i=S_{i+p^k}。但是这样的话又相当于 Si=Si+gcd(pk,n)S_i=S_{i+\gcd(p^k,n)}(注意到下标都是 modn\bmod n 意义下的,所以根据裴蜀定理存在 apk+bn=gcd(pk,n)ap^k+bn=\gcd(p^k,n),于是 Si=Si+apk=Si+apk+bn=Si+gcd(pk,n)S_i=S_{i+ap^k}=S_{i+ap^k+bn}=S_{i+\gcd(p^k,n)})。

    那么考虑如果 nnpp 的次数是 tt(即 ptn,pt+1 ⁣ ⁣∤np^t|n,p^{t+1}\!\!\not|\,n),则 Si=Si+pk(k>t)    Si=Si+ptS_i=S_{i+p^k}(k>t)\implies S_i=S_{i+p^t}。于是如果 SSptp^t 阶差分不全为 00,则它的任意阶差分都不全为 00(否则如果存在 a>pta>p^t 阶差分全为 00,则找一个 pkap^k\geq a,那么显然 pkp^k 阶差分也全为 00,因此 ptp^t 阶差分为 00,与上面的假设矛盾)。


    既然 ptp^t 阶差分全为 00,这就说明 Si=Si+ptS_i=S_{i+p^t}。因此这个序列是一个周期为 ptp^t 的序列,那么我们就可以只保留它的前 ptp^t 项(因为它差分之后仍然是一个周期为 ptp^t 的序列,相当于我们把周期为 NN 的一个环变成了周期为 ptp^t 的一个环)。

    假设答案为 uu,那么如果 upt1u\leq p^{t-1}(这可以扫一遍判断出来),则说明这个序列是一个周期为 pt1p^{t-1} 的序列,只保留它的前 t1t-1 项之后递归处理即可;否则的话就把序列做一次 pt1p^{t-1} 阶差分继续处理。由于这个序列 ptp^t 阶差分是 00,所以至多 pp 次之后就会递归。

    复杂度则为

    T(n)=T(n/p)+O(np)=O(p(n+n/p+n/p2+))=O(np)T(n)=T(n/p)+O(np)=O(p(n+n/p+n/p^2+\dots))=O(np)

    代码:

    #include <algorithm>
    #include <cctype>
    #include <cstdio>
    #include <cstring>
    
    typedef long long LL;
    
    int read() {
      int ans = 0, c, f = 1;
      while (!isdigit(c = getchar()))
        if (c == '-') f *= -1;
      do ans = ans * 10 + c - '0';
      while (isdigit(c = getchar()));
      return ans * f;
    }
    
    const int N = 300050;
    
    int A[N], B[N], n, p;
    
    bool check(int q) {
      // A[i] == A[(i + q) % n]
      for (int i = 0; i < n; ++i)
        if (A[i] != A[(i + q) % n])
          return false;
      return true;
    }
    
    void modify(int q) {
      for (int i = 0; i < n; ++i)
        B[i] = (A[i] - A[(i + q) % n] + p) % p;
      memcpy(A, B, n * sizeof(int));
    }
    
    int main() {
      n = read(); p = read();
      for (int i = 0; i < n; ++i) A[i] = read() % p;
      int t = 1;
      while (n % (t * p) == 0) t *= p;
      if (!check(t)) {
        puts("-1");
        return 0;
      }
      int ans = 0;
      n = t;
      while (n > 1) {
        t = n / p;
        while (!check(t))
          modify(t), ans += t;
        n = t;
      }
      if (A[0] != 0) ++ans;
      printf("%d\n", ans);
    }
    
    • 1

    [THUPC 2019] 令人难以忘记的题目名称

    信息

    ID
    4365
    时间
    2000ms
    内存
    500MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者