2022ICPC网络赛第二场 - A
构造 + 费马小定理
2022ICPC网络赛(II)A
[题目详情 - A Yet Another Remainder (pintia.cn)](https://codeforces.com/contest/1734/problem/E)
题意
有一个大整数 , 给出 的十进制位数为 , 设从高到低位的数为 , 并给出 行信息 ,第 行有 个数,
表示 for (int k = j; k <= n; k += i) b[i][j] += a[i];
有 组询问,每组给出一个素数 , 求 的结果
思路
-
首先关于同余的题目,最好下标从 0 开始,因此先把题干下标由低位到高位是 改成从低位到高位分别是 , 把 预处理一下
-
再思考 是什么含义, 其实是 数组的下标,在模 意义下,同余于 的所有数之和
-
肯定不会是让把 全部求出来,很可能是要通过 把 拼出来
-
由于答案并非求 , 而是求 的值,就转化为找一个较好拼凑出的 , 满足
-
通过暴力验证可以发现,对于任何一个素数 ,都能在 100 以内找到一个 , 使得
(这里其实用费马小定理就可以,)
因此
用 b矩阵的第 行乘相应的系数就可拼凑出上式
- n 较小时可能不存在第 行, 要暴力特判
代码
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define ALL(x) x.begin(),x.end()
#define SZ(x) x.size()
typedef long long ll;
inline ll _read() {
static ll ans;
static unsigned int c;
static bool p;
for (c = getchar(); c != '-' && (c < '0' || c > '9'); c = getchar());
if (c == '-') p = false, c = getchar(); else p = true;
for (ans = 0; c <= '9' && c >= '0'; c = getchar()) ans = ans * 10 + c - '0';
return p ? ans : -ans;
}
const int N = 110;
int pr[N], cnt;
bool st[N];
void get_primes(int n)
{
memset(st, true, sizeof st);
st[1] = false;
for (int i = 2; i <= n; i++)
{
if (st[i])
pr[++cnt] = i;
for (int j = 1; j <= cnt && pr[j] <= n / i; j++)
{
int p = pr[j];
st[i * p] = false;
if (i % p == 0)
break;
}
}
}
ll qmi(ll a, ll b, ll p)
{
ll ans = 1;
while(b)
{
if (b & 1)
ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans % p;
}
int id[N];
void presolve()
{
for (int j = 1; j <= cnt; j++)
{
int p = pr[j];
for (int i = 1; i <= 99; i++)
{
if (qmi(10, i, p) == 1)
{
id[p] = i;
break;
}
}
}
}
ll b[N][N];
int n, q;
int p;
ll solve()
{
p = _read();
int len = id[p];
ll ans = 0;
for (int i = 0; i < len; i++)
{
ans += b[len][i] * qmi(10, i, p) % p;
if (ans >= p)
ans -= p;
}
return ans;
}
void solve2()
{
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < i; j++)
b[i][j] = _read();
}
q = _read();
while(q--)
{
p = _read();
ll ans = 0;
for (int i = 0; i < n; i++)
{
ans += qmi(10, n - i - 1, p) * b[n][i] % p;
if (ans >= p)
ans -= p;
}
printf("%lld\n", ans);
}
}
int main() {
get_primes(99);
presolve();
int T = _read();
while(T--)
{
n = _read();
if (n <= 100)
{
solve2();
continue;
}
for (int i = 1; i <= 100; i++)
{
for (int j = 0; j < i; j++)
{
int jj = j + 1;
int r = (n - jj) / i * i + jj - 1;
r = n - 1 - r;
b[i][r] = _read();
}
}
q = _read();
while(q--)
{
ll ans = solve();
printf("%lld\n", ans);
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!