首页 > 其他分享 >Atcoder ARC058E Iroha and Haiku

Atcoder ARC058E Iroha and Haiku

时间:2023-07-24 09:02:31浏览次数:36  
标签:Atcoder le 10 后缀 times Haiku Iroha

题目中的式子转化一下即存在一位 \(i\) 使得到 \(i\) 时的后缀和存在 \(X + Y + Z, Y + Z, Z\),再发现 \(X + Y + Z\le 17\),考虑状压。

设 \(f_{i, j}\) 为填了 \(i\) 个数当前后缀和中存在的数的状态为 \(j\)(只存 \(0\sim X + Y + Z\) 的数是否存在)的方案数。
考虑转移,则下一位可以填上 \(1\sim 10\) 的数,对应的后缀和就应左移对应位数同时 \(+1\) 代表存在后缀为 \(0\),\(f_{i + 1, j\times 2^d + 1}\leftarrow f_{i + 1, j\times 2^d + 1} + f_{i, j}(1\le j\le 10)\)。

统计答案考虑若在第 \(i\) 个数满足条件就直接加上答案不继续往后转移,否则可能会算漏一部分。
当 \(j\) 对应的存在状态中已存在 \(X + Y + Z, Y + Z, Z\) 时,后面的 \(n - i\) 位就可以任意填了,对应的方案数就为 \(f_{i, j}\times 10^{n - i}\),对所有满足条件的状态按照此式子求和即可。

时间复杂度 \(O(nW\times 2^{X + Y + Z})\),\(W\) 为值域,此题为 \(10\)。

// lhzawa(https://www.cnblogs.com/lhzawa/)
// Problem: E - Iroha and Haiku
// Contest: AtCoder - AtCoder Regular Contest 058
// URL: https://atcoder.jp/contests/arc058/tasks/arc058_c
// Memory Limit: 512 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
const int N = 40 + 2, M = 18;
int f[N][1 << M];
int p10[N];
const int mod = 1e9 + 7;
int main() {
	p10[0] = 1;
	for (int i = 1; i <= 40; i++) {
		p10[i] = 1ll * p10[i - 1] * 10 % mod;
	}
	int n, X, Y, Z;
	scanf("%d%d%d%d", &n, &X, &Y, &Z);
	int lim = (1 << (X + Y + Z + 1)) - 1, orz = (1 << (X + Y + Z)) | (1 << (Y + Z)) | (1 << Z);
	int ans = 0;
	f[0][1] = 1;
	for (int i = 0; i <= n; i++) {
		for (int j = 0; j <= lim; j++) {
			if ((j & orz) == orz) {
				ans = (ans + 1ll * f[i][j] * p10[n - i] % mod) % mod;
				continue;
			}
			for (int s = 1; s <= 10; s++) {
				f[i + 1][(j << s | 1) & lim] = (f[i + 1][(j << s | 1) & lim] + f[i][j]) % mod;
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}

标签:Atcoder,le,10,后缀,times,Haiku,Iroha
From: https://www.cnblogs.com/lhzawa/p/17576346.html

相关文章

  • 「解题报告」Toyota Programming Contest 2023#4(AtCoder Beginner Contest 311)
    比赛地址:ToyotaProgrammingContest2023#4(AtCoderBeginnerContest311)-AtCoder后记:大家都太强了%%%,如果我做不出第四题就要掉分了。。。A-FirstABCA-FirstABC(atcoder.jp)找到第一个\(\texttt{A,B,C}\)三种字符都出现的位置。/*Thecodewaswrittenby......
  • Atcoder ARC058B Iroha and a Grid
    考虑从第\(b\)列与第\(b+1\)之间分开这个矩阵,钦定\((i,b)\)下一步必须走到\((i,b+1)\),可以发现这样是不会漏算或算重的。于是就可以用乘法原理算出这个\(i\)的贡献:\(\binom{(i-1)+(b-1)}{i-1}\times\binom{(n-i)+(m-b-1)}{n-i}\),左半部分的就......
  • 练习记录-AtCoder Beginner Contest 311-(A-E)
    写的还挺顺的F之后补A-FirstABC找abc三个字母什么时候出现了一次输出即可B-VacationTogether题意:最长的几个人一排里面均有时间#include<bits/stdc++.h>#defineclosestd::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)usingnamespacestd;typedeflon......
  • Toyota Programming Contest 2023#4(AtCoder Beginner Contest 311)——D
    https://atcoder.jp/contests/abc311/tasks/abc311_d思路题目说如果当前方向的下一个点能走,那么就一直走,否则才能转向。根据题意模拟即可,这道题的难点在于,碰到已经走过的点到底要不要走。如果当前方向走到底,其中的点之前全部都走过那么就不能再走了。我们用bfs模拟,对于能一直走......
  • AtCoder Beginner Contest 311 A-E题解
    A-FirstABC题意给一个长度为N的仅由ABC三个字符组成的字符串S,问S中ABC三个字符第一次出现的位置的最大值。题解使用map<char,bool>判重,记录当前不同的字符串的个数cnt,当cnt等于3时,输出此时的下标+1作为答案。Code#include<bits/stdc++.h>usingnamespacestd;usingll......
  • AtCoder Beginner Contest 311
    A-FirstABC(abc311A)题目大意给定一个字符串,问最短的一个前缀,包含ABC这三个字符。解题思路注意到这个前缀的末尾字母一定是这三个字母中的一个,因此答案就是这三个字母出现位置最早的最大值。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=lo......
  • Atcoder Regular Contest 154 E - Reverse and Inversion
    只要你发现是诈骗题就好办了。不要像我那样傻傻地瞪一个小时然后才发现那俩sigma里的东西相减是有性质的。先考虑计算单个\(f(p)\),一眼的树状数组……吗?考虑最终答案式子里\(i\)的系数:\(\sum\limits_{j<i}[p_j>p_i]-\sum\limits_{j>i}[p_j<p_i]\),因为\(\sum\limits_{j<i}[p......
  • Atcoder Regular Contest 124 E - Pass to Next
    首先第一步是一个浅显的观察:我们要求的是所有可能的最终序列的贡献之和,如果能改为计算所有操作序列的贡献之和那问题会简单很多,并且我们惊奇地发现,如果一组\(x_i\)全大于\(0\),那么把它们全减去\(1\)以后得到的答案序列不会改变,而对于任意一种可能的最终序列,必然存在一组\(\m......
  • Atcoder Grand Contest 057 D - Sum Avoidance
    先来找些性质:\(A\)中最小的元素\(M\)肯定是最小的不是\(S\)的因子的数,由于\(\text{lcm}(1,2,3,\cdots,43)>10^{18}\),所以\(M\le43\)。对于每个\(0\lei<M\),\(\bmodM=i\)的数被选择的部分必然是一段后缀,因为如果你选择了\(M\)选择了某个\(\bmodM=i\)的数\(v\),......
  • AtCoder Grand Contest 049 E Increment Decrement
    洛谷传送门AtCoder传送门好题。同时考查了slopetrick和选手的计数能力,不愧是AGCE。先考虑问题的第一部分。你现在有一个初始全为\(0\)的序列\(b\)。你每次可以给\(b\)单点\(\pm1\),代价为\(1\),或区间\(\pm1\),代价为\(m\)。求把\(b\)变成给定序列\(a\)的......