[洛谷][LGR-303-Div.2]洛谷 10 月月赛 I &「WWOI」Round 4 A,B题题解

Q:为什么写这篇题解?

ans: 闲的 这次题目都很有意思

Q:为什么只有前两题?

ans:三四不会 前两题比较有代表性


AI使用提示

本文少量markdown语法部分使用AI辅助生成,自己手搓太麻烦,但保证所有思路均为自己的

正文

T817800 「WWOI R4」二五一十

题目传送门

1. 题目大意&定义

一个正整数 \(x\) 的有效长度,就是去掉它末尾所有连续的 0 之后,剩余十进制串的长度。

而末尾的 0 来自因子 \(10 = 2 \times 5\)。
因此,去掉末尾的 0,等价于把数中成对的 \(2\) 和 \(5\) 因子全部消去。


二:详细步骤:

1. 分解原数

设原数为 \(n\)。把它分解成:

\[n = 2^a \times 5^b \times m \]

其中 \(m\) 不能再被 \(2\) 或 \(5\) 整除,即 \(m\) 与 \(10\) 互质。

例如:

  • \(182375 = 5^3 \times 1459\),所以 \(m = 1459\)
  • \(182376 = 2^3 \times 22797\),所以 \(m = 22797\)
  • \(2147483648 = 2^{31}\),所以 \(m = 1\)

2. 操作后的样子

我们可以进行任意次乘 \(2\) 或乘 \(5\) 操作。
假设分别乘了 \(2^x\) 和 \(5^y\),那么结果变为:

\[2^{a+x} \times 5^{b+y} \times m \]

去掉末尾所有 0,相当于除以 \(10^{\min(a+x,\ b+y)}\)。

分两种情况:

  • 如果 \(a+x \le b+y\),则有效部分为:

\[5^{(b+y)-(a+x)} \times m = 5^d \times m \]

  • 如果 \(b+y \le a+x\),则有效部分为:

\[2^{(a+x)-(b+y)} \times m = 2^d \times m \]

其中 \(d \ge 0\)。

也就是说,无论怎么操作,最终的有效部分一定是:

\[m \times 2^d \quad \text{或} \quad m \times 5^d \]

其中 \(d \ge 0\)。


三. 正确性证明

因为 \(2^d \ge 1\),\(5^d \ge 1\),所以:

\[m \times 2^d \ge m,\qquad m \times 5^d \ge m \]

乘以一个不小于 \(1\) 的正整数,不会让十进制位数减少。
因此有效部分的位数一定不小于 \(m\) 的位数。

另一方面,我们完全可以不进行任何操作,或者只乘以 \(10\) 的幂(即同时乘 \(2\) 和 \(5\)),这样末尾只会增加 0,去掉后有效部分仍然是 \(m\)。

所以最小有效长度就是 \(m\) 的十进制位数。


5. 算法代码步骤

对于每组数据:

  1. 读入正整数 \(n\)。
  2. 不断除以 \(2\),直到 \(n\) 不能再被 \(2\) 整除:
while n % 2 == 0: n /= 2
  1. 不断除以 \(5\),直到 \(n\) 不能再被 \(5\) 整除:
while n % 5 == 0: n /= 5
  1. 此时得到的 \(n\) 就是 \(m\)。
  2. 计算 \(m\) 的十进制位数:
ans = 0
while m > 0:
    ans += 1
    m /= 10
  1. 输出 \(ans\)。

6. 复杂度分析(AI计算)

  • 每组数据最多除以 \(2\) 约 \(60\) 次,除以 \(5\) 约 \(26\) 次。
  • 计算位数最多 \(19\) 次。
  • 总时间复杂度约为 \(O(T \log n)\),在 \(T \le 10^6\)、\(n \le 10^{18}\) 下可以接受。
  • 需要使用 64 位整数,并建议使用快速输入输出。

7. 样例验证

输入 \(n\) 分解后 \(m\) \(m\) 的位数 输出
1 1 1 1
182375 1459 4 4
182376 22797 5 5
2147483648 1 1 1
1000000000000000000 1 1 1
999999999999999999 999999999999999999 18 18

全部符合样例。

code:

#include<bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int s;
    cin >> s;
    while (s--) {
        long long n;
        cin >> n;

        while (n % 2 == 0) n /= 2;
        while (n % 5 == 0) n /= 5;

        int len = 0;
        while (n > 0) {
            len++;
            n /= 10;
        }

        cout << len << endl;
    }
    return 0;
}

题目二

T783160 「WWOI R4」构造大师

题目传送门

这道题我认为非常有意思,很复杂的题目条件,但只需要不到20行代码即可解决,本质数学题。


1. 题目dayi

给定奇数 \(n\) 和 \(1 \le k \le n-1\),需要构造长度为 \(n\) 的数组 \(a,b\),使得

\[\begin{aligned} S_1 &= \{(a_i+a_{i+1}) \bmod 3n \mid 1\le i\le n\},\quad a_{n+1}=a_1,\\ S_2 &= \{(a_i+b_i) \bmod 3n \mid 1\le i\le n\},\\ S_3 &= \{(b_i+b_{i+k}) \bmod 3n \mid 1\le i\le n\},\quad b_{i+n}=b_i, \end{aligned} \]

满足 \(|S_1\cup S_2\cup S_3|=3n\)。

因为每个集合最多有 \(n\) 个元素,而总共有 \(3n\) 个模 \(3n\) 的剩余类,所以条件等价于:

  • 每个集合内部元素互不相同;
  • 三个集合两两不交;
  • 并集恰好为 \(\{0,1,\dots,3n-1\}\)。

2. 数学部分

模 \(3n\) 的剩余类可以按照模 \(3\) 的余数分成三组,每组恰好有 \(n\) 个数:

\[\begin{aligned} A_0 &= \{0,3,6,\dots,3n-3\},\\ A_1 &= \{1,4,7,\dots,3n-2\},\\ A_2 &= \{2,5,8,\dots,3n-1\}. \end{aligned} \]

如果我们能

\[S_1 \subseteq A_0,\qquad S_2 \subseteq A_1,\qquad S_3 \subseteq A_2, \]

并且每个集合的大小都是 \(n\),那么它们必然分别等于 \(A_0,A_1,A_2\),从而并集就是全体。

所以我们只需要构造 \(a,b\) 使得:

  • 所有 \(a_i \equiv 0 \pmod 3\),从而 \(a_i+a_{i+1}\equiv 0\pmod 3\);
  • 所有 \(b_i \equiv 1 \pmod 3\),从而 \(a_i+b_i\equiv 1\pmod 3\),且 \(b_i+b_{i+k}\equiv 2\pmod 3\)。

3. 构造方式

\[a_i = 3(i-1),\qquad b_i = 3(i-1)+1,\qquad i=1,2,\dots,n. \]

即

\[\begin{aligned} a &= [0,3,6,\dots,3(n-1)],\\ b &= [1,4,7,\dots,3(n-1)+1]. \end{aligned} \]

这些数都在 \(0\) 到 \(3n-1\) 之间。


4. 正确性证明(部分AI写markdown)

(1) 模 \(3\) 性质

  • \(a_i \equiv 0 \pmod 3\),所以 \(a_i+a_{i+1}\equiv 0\pmod 3\),即 \(S_1\subseteq A_0\)。
  • \(b_i \equiv 1 \pmod 3\),所以 \(a_i+b_i\equiv 1\pmod 3\),即 \(S_2\subseteq A_1\)。
  • \(b_i+b_{i+k}\equiv 1+1\equiv 2\pmod 3\),即 \(S_3\subseteq A_2\)。

三个集合分别放在三个不同的模 \(3\) 数字类,肯定互不相交。

(2) 每个集合恰好取遍对应模 \(3\) 类的所有数

只需证明每个集合内部元素互不相同,且各有 \(n\) 个。

对于 \(S_1\):

\[a_i+a_{i+1} = 3(i-1)+3i = 3(2i-1)\quad (1\le i\le n-1), \]

\[a_n+a_1 = 3(n-1)+0 = 3(n-1). \]

模 \(3n\) 下,这些值等于 \(3 \cdot ((2i-1)\bmod n)\)(最后一个为 \(3\cdot((n-1)\bmod n)\))。
因为 \(n\) 是奇数,\(\gcd(2,n)=1\),所以 \(i\mapsto 2i-1\pmod n\) 是 \(1,2,\dots,n-1\) 的一个排列,再加上 \(i=n\) 对应的 \(n-1\),正好取遍 \(0,1,\dots,n-1\)。
因此 \(S_1 = \{3k \bmod 3n \mid 0\le k\le n-1\} = A_0\)。

对于 \(S_2\):

\[a_i+b_i = 3(i-1) + (3(i-1)+1) = 6(i-1)+1 = 3\cdot(2(i-1))+1. \]

模 \(3n\) 下,这等于 \(1+3\cdot((2(i-1))\bmod n)\)。
因为 \(2\) 与 \(n\) 互质,\(2(i-1)\bmod n\) 取遍 \(0,1,\dots,n-1\)。
所以 \(S_2 = \{1+3k \mid 0\le k\le n-1\} = A_1\)。

对于 \(S_3\):

\[b_i+b_{i+k} = (3(i-1)+1) + (3(i+k-1)+1) = 3(2i+k-2)+2. \]

模 \(3n\) 下,这等于 \(2+3\cdot((2i+k-2)\bmod n)\)。
当 \(i=1,\dots,n\) 时,\(2i+k-2\pmod n\) 是一个线性函数,因为 \(2\) 与 \(n\) 互质,所以它取遍所有模 \(n\) 的剩余类。
因此 \(S_3 = \{2+3k \mid 0\le k\le n-1\} = A_2\)。

于是

\[S_1\cup S_2\cup S_3 = A_0\cup A_1\cup A_2 = \{0,1,\dots,3n-1\}, \]

并集大小为 \(3n\),满足要求。


5. 复杂度分析

构造只需对 \(i=1,\dots,n\) 直接计算 \(a_i,b_i\),时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。
对于所有测试数据,总 \(n\) 不超过 \(10^6\),可以轻松通过。


6. 样例验证

以 \(n=5,k=2\) 为例,按照本构造:

\[a = [0,3,6,9,12],\qquad b = [1,4,7,10,13]. \]

计算模 \(15\):

  • \(S_1\):

\[a_1+a_2=3,\ a_2+a_3=9,\ a_3+a_4=15\equiv 0,\ a_4+a_5=21\equiv 6,\ a_5+a_1=12 \]

得 \(\{0,3,6,9,12\}\)。

  • \(S_2\):

\[a_i+b_i = 1,7,13,19\equiv 4,25\equiv 10 \]

得 \(\{1,4,7,10,13\}\)。

  • \(S_3\):

\[b_1+b_3=8,\ b_2+b_4=14,\ b_3+b_5=20\equiv 5,\ b_4+b_1=11,\ b_5+b_2=17\equiv 2 \]

得 \(\{2,5,8,11,14\}\)。

三个集合的并集正好是 \(\{0,1,2,\dots,14\}\),满足条件。


7. 结论

对于任意奇数 \(n\) 和任意 \(1\le k\le n-1\),答案总是 Yes。
一种简单且通用的构造是:

\[\boxed{a_i = 3(i-1),\qquad b_i = 3(i-1)+1,\qquad i=1,2,\dots,n.} \]

直接输出即可。

code:

#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, k;
    cin >> n >> k;

    cout << "Yes" << '\n';

    for (int i = 1; i <= n; ++i) {
        cout << 3 * i - 3 << (i == n ? '\n' : ' ');
    }

    for (int i = 1; i <= n; ++i) {
        cout << 3 * i - 2 << (i == n ? '\n' : ' ');
    }

    return 0;
}

后记

第一题其实我第一遍交没过,原因是 TLE,但是加入

ios::sync_with_stdio(false);
cin.tie(nullptr);

就过了,这显然打脸了***说过的“我至今没有见过任何题加入优化输入输出流后变 AC”,嘻嘻。

其次这篇题解我真的写的很认真,找数学符号对应的 Markdown 真的很麻烦,整篇写下来花了很长时间,点个赞吧 QAQ

posted @ 2026-10-01 18:37  Spencer20262026  阅读(16)  评论(0)    收藏  举报