首页 > 其他分享 >ABC338G evall 题解

ABC338G evall 题解

时间:2024-02-28 17:35:58浏览次数:21  
标签:num1 题解 ABC338G num MAXN evall pos2 dp pos1

题意:给定一个由数字和加号和乘号组成的字符串,求出 \(\sum s(i,j)\)。其中 \(s(i,j)\) 表示 \(i\) 到 \(j\) 字符组成的表达式的值。

考虑 \(\text{dp}\)。

设 \(dp_{i}\) 表示以 \(i\) 为起点的所有表达式的值之和。那么我们考虑以一些加号作为分界点来转移。

假设 \(i\) 右边最近的加号的位置为 \(pos1\),并且 \(i\) 到 \(pos1-1\) 组成的数为 \(num1\),设 \(cnt_i\) 表示在 \(i\) 之后可能有多少个右端点(即有多少个数字)。那么终点在 \(pos1\) 后面的所有情况的和为 \(num1 \times cnt_i + dp_{pos1+1}\)。

接下来考虑右端点在 \(pos1\) 前面的情况,这一定是一个连乘的形式,设 \(pos2\) 表示 \(i\) 右边最近的乘号,\(num\) 表示 \(i\) 到 \(pos2-1\) 组成的数,这也同样可以 \(\text{dp}\)。

设 \(s0_i\) 表示从 \(i\) 开始的所有数之和(直到有符号),\(s1_i\) 表示从 \(i\) 开始的所有连乘之和(直到有加号)。那么有转移:

\[s0_i=s0_{i+1}+a_i \times (10^0+10^1+\dots+10^{pos2-i-1}) \]

\[s1_i=num \times s1_{pos2+1}+s0_i \]

最终 \(dp_i\) 的值则为 \(dp_{pos1+1} + num1 \times cnt_i + s1_i\)。

答案即为 \(\sum_{i=1}^{n} dp_i\)。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 1e6 + 10;
const int mod = 998244353;
int dp[MAXN],sum[MAXN],p[MAXN],cnt[MAXN],n,ans,pos1,pos2,s0[MAXN],s1[MAXN],num,num1;
char a[MAXN]; 
bool flag = 1;
signed main()
{
	cin >> (a + 1);
	n = strlen(a + 1),p[0] = 1;
	pos1 = pos2 = n + 1;
	sum[0] = 1;
	for(int i = 1;i <= n;i++) 
	{
		p[i] = p[i - 1] * 10 % mod;
		sum[i] = (sum[i - 1] + p[i]) % mod;
	}
	for(int i = n;i >= 1;i--) cnt[i] = cnt[i + 1] + (a[i] >= '0' && a[i] <= '9');
	num1 = 1;
	for(int i = n;i >= 1;i--)
	{
		if(a[i] == '+')
		{
			pos1 = i;
			num = 0;
			num1 = 1;
			flag = 1;
		}
		else if(a[i] == '*')
		{
			pos2 = i;
			num1 = (num1 * num) % mod;
			num = 0;
			flag = 0;
		}
		else
		{
			num = (num + (a[i] - '0') * p[min(pos1,pos2) - i - 1]) % mod;
//			cout << "i = " << i << " num = " << num << " num1 = " << num1 << endl;
			s0[i] = (s0[i + 1] + (a[i] - '0') * sum[min(pos2,pos1) - i - 1] % mod) % mod;
			s1[i] = ((flag == 0 ? num * s1[pos2 + 1] % mod : 0) + s0[i]) % mod;
			dp[i] = (dp[pos1 + 1] + s1[i] + num * num1 % mod * cnt[pos1] % mod) % mod;
//			cout << "s0 = " << s0[i] << " s1 = " << s1[i] << " dp = " << dp[i] << endl;
		}
	}
	for(int i = 1;i <= n;i++)
	{
		ans = (ans + dp[i]) % mod;
	}
	cout << ans;
	return 0;
}

标签:num1,题解,ABC338G,num,MAXN,evall,pos2,dp,pos1
From: https://www.cnblogs.com/Creeperl/p/18041173

相关文章

  • CF1209G2 Into Blocks (hard version) 题解
    Description给你\(n\),\(q\),\(n\)表示序列长度,\(q\)表示操作次数。我们需要达成这么一个目标状态:如果存在\(x\)这个元素,那么必须满足所有\(x\)元素都必须在序列中连续。然后你可以进行这么一种操作,将所有的\(x\)元素的变为任意你指定的\(y\)元素,并且花费\(cnt[x......
  • 2024牛客寒假算法基础集训营6 题解 ( A,B,C,D,E,I)
    2024牛客寒假算法基础集训营6题解(A,B,C,D,E,I)A 宇宙的终结题意找到\([l,r]\)区间中有多少数恰好等于三个不同素数的乘积思路数据范围很小,可以考虑暴力,遍历\([l,r]\)区间内每个数,拿每个小于当前数的素数一直往下除,判断是否存在能被恰好3个素数整除的情况代码/********......
  • 题解 NKOJ2929 【[THUSC2014] 函数求解】
    代码:#include<iostream>#include<queue>#include<cstdio>#include<cmath>usingnamespacestd;typedefstruct{ intnxt; intend; intdis; doublecost;}Edge;constintN=2e3,M=400+7,K=80800+7;constdoubleep......
  • ABC294 EFG 题解
    E-2xNGrid题意给你一个\(2\timesL\)的网格,但是\(L\)很大,所以用以下形式压缩:将同一个颜色的连续段视为一个整体,那么每一行就可以用若干个二元组\((a_i,b_i)\)表示,其中\(a_i\)为颜色,\(b_i\)为连续段的长度。保证长度\(\le10^5\)。输入以上述形式压缩,现在让你求出......
  • P1110 [ZJOI2007] 报表统计 题解
    考察点:STL的熟练运用。记:\(l_i\)表示序列中不超过\(a_i\)的最大数,\(r_i\)表示序列中超过\(a_i\)的最小数。开一个vectorinsert[N]存储\(a_i\)后面插入的所有数字。首先,我们使用一个multisets1来存储相邻元素的差的绝对值,然后再开一个multisets2来存储当前出......
  • CodeChef Chef and Churus 题解
    对给出的\(n\)个区间分块,设块长为\(B\)。每个块内计算每个位置的贡献(被覆盖次数)。具体地,记\(f_{i,j}\)表示第\(i\)个块第\(j\)个数被覆盖了多少次,这个可以用差分轻松维护。预处理复杂度\(O(\frac{n^2}{B})\)。现在考虑修改。记\(ans_i\)表示块\(i\)的贡献,那么对于......
  • ABC303 G 题解
    区间DP。设\(f_{l,r}\)表示只考虑\([l,r]\),先手得分减后手得分的最大值(并不关心谁是先手谁是后手),区间长度\(len=r-l+1\)。然后对三种情况分别讨论:使用操作一,此时取掉左/右端点的部分先手后手互换,对答案的贡献为\(\max(a_l-f_{l+1,r},a_r-f_{l,r-1})\)。使用操作二,继......
  • P1668 题解
    两种做法。一、最短路题目要求区间数量最小。如果能建出图来,就可以转换为最短路问题。具体地,我们从\(l-1\tor\)连一条长度为\(1\)的边,意味着要多经过\((l-1,r]\)这一个区间。这是左开右闭的形式。现在还有一个问题:通过这种边我们只能到达区间的右端点,如果想向左到达区......
  • P1266 速度限制 题解
    考虑分层图。把图按速度分成\(V\)层,\(f_{i,j}\)表示点\(i\)在第\(j\)层(速度为\(j\))的编号。注意:这里的速度为\(j\)是指到达\(i\)那一条边的速度(\(i\)为终点)。考虑一种naive的建边方式:首先,记当前点为\(u\),速度为\(i\);\(u\)的出边速度为\(j\),长度为\(l\),终点......
  • ABC302 Ex 题解
    首先我们考虑\(v\)固定怎么做。实际上就是ARC111B。考虑建图,对每个\((a_i,b_i)\)建一条无向边,那么问题就变成了:对于每条边都要选择它以及其连接的一个点,最大化选出的点数。很明显可以对每个连通块分开考虑。记当前连通块的点数为\(V\),边数为\(E\)。那么有结论:该连通块对......