https://codeforc.es/problemset/problem/1195/D2

很明显可以看出,任意一个长度为\(l_1\)的数串\(s_1\)和任意一个长度为\(l_2\)的数串\(s_2\)在\(f(s_1,s_2)\)中每个位的贡献的位数是一样的。稍微推一推可以知道,\(calcx\_ijk\)和\(calcy\_ijk\)的公式。然后暴力统计一波各个长度的数串有几个就可以了。小心溢出。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; ll a[100005];
ll di[100005][11];
int cntws[11]; ll gx[11][11][11];
ll gy[11][11][11]; const ll mod = 998244353; int ws(ll x) {
int cnt = 0;
while(x) {
//cout<<x<<" ";
cnt++;
x /= 10;
//cout<<cnt<<endl;
}
return cnt;
} ll ans; ll calc_base(int i,int k){
ll res=0;
for(int j=1;j<=10;j++){
res=(res+1ll*cntws[j]*gx[i][j][k]%mod)%mod;
res=(res+1ll*cntws[j]*gy[i][j][k]%mod)%mod;
}
//cout<<"i="<<i<<" k="<<k<<" res="<<res<<endl;
return res;
} ll calc(ll x) {
ll res = 0;
int i=ws(x);
for(int k=1;k<=i;k++){
ll r = x%10;
res = (res + calc_base(i,k)* r % mod) % mod;
x /= 10;
}
return res % mod;
} ll p10[23]; ll calc_ijk(int i, int j, int k) {
if(k <= j) {
return p10[k * 2];
} else {
return p10[j + k];
}
} ll calc_ijk2(int i, int j, int k) {
if(k <= j) {
return p10[k * 2 - 1];
} else {
return p10[j + k];
}
} void init_gx() {
memset(gx, 0, sizeof(gx));
//gx[i][j][k]i是x,j是y的时候,导致i的第k位贡献的位数
//gy[i][j][k]i是x,j是y的时候,导致j的第k位贡献的位数
for(int i = 1; i <= 10; i++) {
for(int j = 1; j <= 10; j++) {
for(int k = 1; k <= i; k++) {
gx[i][j][k] = calc_ijk(i, j, k);
}
}
}
memset(gy, 0, sizeof(gy));
//gx[i][j]i是x,j是y的时候,导致i贡献的位数
//gy[i][j]i是x,j是y的时候,导致j贡献的位数
for(int i = 1; i <= 10; i++) {
for(int j = 1; j <= 10; j++) {
for(int k = 1; k <= i; k++) {
gy[i][j][k] = calc_ijk2(i, j, k);
}
}
}
} int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
//freopen("Yinku.out", "w", stdout);
#endif // Yinku
p10[1] = 1;
for(int i = 2; i <= 21; i++) {
p10[i] = p10[i - 1] * 10ll % mod;
//cout<<p10[i]<<endl;
}
int n;
init_gx();
for(int i = 1; i <= 2; i++) {
for(int j = 1; j <= 2; j++) {
for(int k = 1; k <= i; k++) {
gx[i][j][k] %= mod;
gy[i][j][k] %= mod;
//printf("%lld ",gx[i][j][k]);
//printf("%lld",gy[i][j][k]);
}
//printf("\n");
}
//printf("\n");
}
while(~scanf("%d", &n)) {
memset(cntws, 0, sizeof(cntws));
for(int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
cntws[ws(a[i])]++;
//cout<<ws(a[i])<<endl;
}
/*for(int i = 1; i <= 10; ++i) {
//cout<<cntws[i]<<endl;
}*/
ans = 0;
for(int i = 1; i <= n; i++) {
ans = (ans + calc(a[i])) % mod;
//printf("ans=%lld\n", ans % mod);
}
printf("%lld\n", ans % mod);
}
}

发现其实可以缩写成下面的形式:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int mod = 998244353; int a[100005];
int lena[100005];
int cntlen[11]; int g[11][11][11]; int len(int x) {
int cnt = 0;
while(x) {
cnt++;
x /= 10;
}
return cnt;
} ll ans; ll calc_base(int i, int k) {
ll res = 0;
for(int j = 1; j <= 10; j++)
res = (res + 1ll * g[i][j][k] * cntlen[j] % mod) % mod;
return res;
} ll calc(int x, int lenx) {
ll res = 0;
for(int k = 1; k <= lenx; k++) {
int r = x % 10;
res = (res + calc_base(lenx, k) * r % mod) % mod;
x /= 10;
}
return res % mod;
} int p10[21]; void init_g() {
memset(g, 0, sizeof(g));
//g[i][j][k]是两个数分别是i位,j位时候,导致长度为i的第k位发生的贡献
for(int i = 1; i <= 10; i++)
for(int j = 1; j <= 10; j++)
for(int k = 1; k <= i; k++)
g[i][j][k] = (p10[k + ((k <= j) ? k : j)] + p10[k + ((k <= j) ? (k - 1) : j)]) % mod;
} void init_p10() {
p10[1] = 1;
for(int i = 2; i <= 20; i++) {
p10[i] = p10[i - 1] * 10ll % mod;
}
} int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
//freopen("Yinku.out", "w", stdout);
#endif // Yinku
init_p10();
init_g();
int n;
while(~scanf("%d", &n)) {
memset(cntlen, 0, sizeof(cntlen));
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
lena[i] = len(a[i]);
cntlen[lena[i]]++;;
}
ans = 0;
for(int i = 1; i <= n; i++) {
ans = (ans + calc(a[i], lena[i])) % mod;
}
printf("%lld\n", ans);
}
}

Codeforces - 1195D2 - Submarine in the Rybinsk Sea (hard edition) - 组合数学的更多相关文章

  1. Codeforces - 1195D1 - Submarine in the Rybinsk Sea (easy edition) - 水题

    https://codeforc.es/contest/1195/problem/D1 给\(n\)个等长的十进制数串,定义操作\(f(x,y)\)的结果是"从\(y\)的末尾开始一个一个交 ...

  2. Codeforces Round #574 (Div. 2) D2. Submarine in the Rybinsk Sea (hard edition) 【计算贡献】

    一.题目 D2. Submarine in the Rybinsk Sea (hard edition) 二.分析 相比于简单版本,它的复杂地方在于对于不同长度,可能对每个点的贡献可能是有差异的. 但 ...

  3. Codeforces Round #574 (Div. 2) D1. Submarine in the Rybinsk Sea (easy edition) 【计算贡献】

    一.题目 D1. Submarine in the Rybinsk Sea (easy edition) 二.分析 简单版本的话,因为给定的a的长度都是定的,那么我们就无需去考虑其他的,只用计算ai的 ...

  4. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 /* 题意:在n^n的海洋里是否有k块陆地 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 输出完k个L后,之后全部输出S:) 5 10 的例子可以是这样的: LSLS ...

  5. codeforces 1195D2-Submarine in the Rybinsk Sea

    传送门:QAQQAQ 题意:自己看 思路:就是一个类似于数位DP的东西... 统计a[i]数位分解的数在每一位出现的个数,即分两种讨论: 1.位数小于当前j,则j会出现在q+i,而且计算顺序互换会计算 ...

  6. Codeforces Round #302 (Div. 2) B. Sea and Islands 构造

    B. Sea and Islands Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544/p ...

  7. Codeforces Round #380 (Div. 2)/729D Sea Battle 思维题

    Galya is playing one-dimensional Sea Battle on a 1 × n grid. In this game a ships are placed on the ...

  8. Codeforces Round #541 (Div. 2) A.Sea Battle

    链接:https://codeforces.com/contest/1131/problem/A 题意: 给两个矩形,一个再上一个在下,求两个矩形合并的周围一圈的面积. 思路: 因为存在下面矩形宽度大 ...

  9. Codeforces Round #258 (Div. 2) D. Count Good Substrings —— 组合数学

    题目链接:http://codeforces.com/problemset/problem/451/D D. Count Good Substrings time limit per test 2 s ...

随机推荐

  1. Python单例模式的设计与实现【完美版】

    目录 1. 按 2. 本文地址 3. 通过继承单例父类来实现 4. 使用装饰器实现 4.1. 懒汉式 4.2. 饿汉式 4.2.1. 未加锁版 4.2.2. 加锁版 1. 按 众所周知,对象是解决继承 ...

  2. more - 在显示器上阅读文件的过滤器

    总览 (SYNOPSIS) more [-dlfpcsu ] [-num ] [+/ pattern] [+ linenum] [file ... ] 描述 (DESCRIPTION) More 是 ...

  3. 利用docker创建包含需要python包的python镜像

    一.拉取python镜像 需要先安装docker,这里读者自行搜索docker的安装过程,下面我们拉取python镜像:以3.7.4为例 docker pull python:3.7.4 二.进入容器 ...

  4. linux命令中chmod 777 以及drwxr-xr-x分别代表什么意思

    最近跟一个运维人员学了点新东西,感觉以前没怎么注意,但现在感觉很有用,特来记录一下. linux使用==ll==命令列出列表的时候,前面总是有一堆drwxr-xr-x ,这些代表什么意思从来还没有去在 ...

  5. Linux 部署或升级openssh7.5p1

    运维Linux系统,部署或升级openssh是经常面临的事,以下已redhat6和redhat7为例. 在redhat6中部署openssh会有什么坑,在编辑openssh源码包时会报一些类似的错误, ...

  6. linux文档和目录结构

    Linux文件系统结构 Linux通过操作目录来实现对磁盘的读写.Linux通过使用正斜杠" / "来表示目录. Linux通过建立一个根目录,所有的目录都是通过根目录衍生出来的. ...

  7. Flink 在人工智能领域的应用实践

    人工智能是未来十年最重要的技术革命与驱动力,在各行各业产生着日益重要的作用,它与大数据的发展相辅相成,不仅推动人类社会迈入更智慧的世界,也为数据的应用带来无可估量的价值. 11 月 28 - 30 日 ...

  8. MyCat的启动

    启动MyCat: ./mycat start 查看启动状态: ./mycat status 停止: ./mycat stop 重启: ./mycat restart 

  9. C++ Standard Template Library (STL) 高级容器

    更多 STL 数据结构请阅读 NOIp 数据结构专题总结(STL structure 章节) std::map Definition: template < class Key, // map: ...

  10. python中时间戳,datetime 和时间字符串之间得转换

    # datetime时间转为字符串def Changestr(datetime1):    str1 = datetime1.strftime('%Y-%m-%d %H:%M:%S')    retu ...