Codeforces - 1195D2 - Submarine in the Rybinsk Sea (hard edition) - 组合数学
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) - 组合数学的更多相关文章
- Codeforces - 1195D1 - Submarine in the Rybinsk Sea (easy edition) - 水题
https://codeforc.es/contest/1195/problem/D1 给\(n\)个等长的十进制数串,定义操作\(f(x,y)\)的结果是"从\(y\)的末尾开始一个一个交 ...
- Codeforces Round #574 (Div. 2) D2. Submarine in the Rybinsk Sea (hard edition) 【计算贡献】
一.题目 D2. Submarine in the Rybinsk Sea (hard edition) 二.分析 相比于简单版本,它的复杂地方在于对于不同长度,可能对每个点的贡献可能是有差异的. 但 ...
- Codeforces Round #574 (Div. 2) D1. Submarine in the Rybinsk Sea (easy edition) 【计算贡献】
一.题目 D1. Submarine in the Rybinsk Sea (easy edition) 二.分析 简单版本的话,因为给定的a的长度都是定的,那么我们就无需去考虑其他的,只用计算ai的 ...
- 构造 Codeforces Round #302 (Div. 2) B Sea and Islands
题目传送门 /* 题意:在n^n的海洋里是否有k块陆地 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 输出完k个L后,之后全部输出S:) 5 10 的例子可以是这样的: LSLS ...
- codeforces 1195D2-Submarine in the Rybinsk Sea
传送门:QAQQAQ 题意:自己看 思路:就是一个类似于数位DP的东西... 统计a[i]数位分解的数在每一位出现的个数,即分两种讨论: 1.位数小于当前j,则j会出现在q+i,而且计算顺序互换会计算 ...
- 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 ...
- 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 ...
- Codeforces Round #541 (Div. 2) A.Sea Battle
链接:https://codeforces.com/contest/1131/problem/A 题意: 给两个矩形,一个再上一个在下,求两个矩形合并的周围一圈的面积. 思路: 因为存在下面矩形宽度大 ...
- 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 ...
随机推荐
- js url传参,参数加密
前台 function encode64(input) { var output = ""; var base = new Base64(); var output = base. ...
- 学Python的第六天
今天发愤图强,死学Python!!!! 为此小编还买了自己喜欢的McPython! 从小老师就说兴趣是最好的老师,所以呢买这本书是想通过我的世界这款游戏来提高自己的学习兴趣!!! 当然也有私心啦... ...
- 你不知道的hostname命令
一般hostname可以获取主机名,但是hostname实际上可以做更多的事情. 让我们先来看看它的帮助. Usage: hostname [-b] {hostname|-F file} set ho ...
- union 横向组合
select sum(zs) zs,sum(zl) zl,sum(ts) ts,sum(lxcbw) lxcbw,sum(bz) bz,sum(sfzqt) sfzqtfrom (select cou ...
- bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...
- thinkphp 响应对象response
1.可以通过修改配置文件的 default_return_type修改输出类型 // 默认输出类型 'default_return_type' => 'html', 2. 可以通过Config类 ...
- springboot2整合logback.xml动态修改日志打印级别
今天找bug烦到了,生产上的日志级别不能修改,非常不利于排查问题,于是想到了动态修改日志打印级别, 因为上一周把项目升级成springboot2,并且使用logback.xml管理日志打印,所以修改也 ...
- OC + RAC (二) Command 命令的用法
-(void)_test2{ ///////////////////////////////////////Command 命令的用法 注意使用command.executionSignals去订阅时 ...
- 小米笔记本pro版bios经常找不到硬盘
自从买了小米笔记本,对小米的印象大大折扣,bios经常找不到硬盘,关机,重启,就好了. 到小米售后,售后说是系统坏了,我说bios里都找不到.他说,系统坏了也会出现这个情况.我说好吧.重做后,没用几天 ...
- php中换行怎么写
PHP中可以用PHP_EOL来替代,以提高代码的源代码级可移植性 unix系列用(推荐学习:PHP编程从入门到精通) 1 windows系列用 1 \r\n mac用 1 如: 1 2 3 4 5 6 ...