[ARC129C] Multiple of 7 题解
题意:
给定一个整数
N
。找到一个由数字
1
到9
组成的字符串s
,满足以下条件:
s
的长度 \(\vert s \vert\) 最多为 \(10^6\)。- 有恰好
N
对整数 \((l,r)\) \((1 \leq l \leq r \leq \vert s \vert)\) 满足以下条件。
- 当将
s
的第l
到第r
个字符提取出来看作一个数时,该数能被 \(7\) 整除。在这个问题的约束条件下,我们可以证明一定存在一种解法。
数据范围:
\(1 \leq N \leq 10^6\)
这个 \(7\) 真的是非常独特啊,因为它是个位数中最大的质数。
同时样例2的 \(\tt{77}\) 也提示了我们,这道题可能需要构造若干 \(\tt{77777}\) 的子串,并拼接他们。
可以发现长度为 \(k\) 的 \(\mathtt{77777}\) 串的贡献为 \(\frac{k(k+1)}{2}\) ,在 \(10^6\) 的限制下实际串上 \(k\) 不会超过 \(2000\) 。
但是问题来了,用什么字符拼接这个 \(\tt{77777}\) 的子串呢?好像如何拼接都可能被卡。
这个时候就要利用 \(\tt{7}\) 的质数性质了。考虑用随机个位数作分隔符。
由于形如 \(\tt{777a77}\) 的数过于特殊,并且需要被质数 \(7\) 整除,所以实际的随机次数不会很多。
时间复杂度 \(\mathcal{O}(cn)\)
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define q779_does_not_have_a_girlfriend true
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(1e5 + 15))
int n,cnt,sum[N],num[N]; string buf;
void init()
{
for(int i = 1; i <= 2333; i++) sum[i] = i * (i + 1) / 2;
}
void solve(int x)
{
for(int l,r; x; )
{
for(l = 1, r = 2222; l < r; )
{
int mid = (l + r + 1) >> 1;
(sum[mid] <= x) ? (l = mid) : (r = mid - 1);
}
x -= sum[l]; num[++cnt] = l;
}
}
string make(int x)
{
string tmp = ""; while(x--) tmp += '7';
return tmp;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("check.in","r",stdin);
// freopen("check.out","w",stdout);
cin >> n; init(); solve(n); mt19937 rd(time(0));
while(q779_does_not_have_a_girlfriend)
{
buf.clear(); for(int i = 1; i <= cnt; i++) {
buf += make(num[i]);
if(i != cnt) buf += char(rd() % 9 + '0');
}
int ok = 0;
for(int i = 0, x = 0; i < buf.size(); i++, x = 0)
for(int j = i; j < buf.size(); j++) {
ok += (!(x = ((x * 10) + buf[j] - '0') % 7));
}
if(ok == n) return cout << buf << '\n', 0;
}
return 0;
}
参考文献:
[1] https://www.luogu.com.cn/blog/275273/solution-at-arc129-c