Solution -「ARC 124E」Pass to Next
\(\mathcal{Description}\)
Link.
有 \(n\) 个人站成一个环,初始时第 \(i\) 个人手里有 \(a_i\) 个球。第 \(i\) 个人可以将自己手中任意数量的求给第 \(i+1\) 个人,第 \(n\) 个人则可以给第 \(1\) 个人。设所有人同时进行一次传球后,第 \(i\) 个人手里有 \(b_i\) 个球,并令 \(B\) 为所有可能的 \(\lang b_n\rang\) 构成的集合,求
\]
\(n\le10^5\)。
\(\mathcal{Solution}\)
首先有一个明显而重要的结论:存在某个人没有给别人球的传球方案一一对应了所有可能的 \(\lang b_n\rang\)。
方法一 从暴力 DP 入手。枚举最小的 \(i=x\),使得 \(x\) 没有向 \(x+1\) 传球,此时令 \(f(i,j)\) 表示第 \(i\) 个人给出 \(j\) 个球时,\(x+1\sim i\) 这一段人的 \(b\) 值的乘积之和。转移时记得讨论当前的 \(i\) 能否不给下一个人球。
写出转移式,似乎很难优化。这时不妨想一想,DP 欲求得的目标是什么? 是 \(f(i,j)\)?并不,应是 \(\sum_j f(i,j)\)。回头看一眼转移,发现我们能直接将转移施加在 \(\sum_j f(i,j)\) 上,状态中的 \(j\) 根本不需要!
下一步优化比较简单:两种情况的转移均能写成 \(2\times2\) 的矩阵,求一求前缀积之类的就内求出答案了。复杂度 \(\mathcal O(n)\)。
方法二 从组合意义入手。\(\prod b_i\) 即传完求后,每个人再从手里的球里选出一个的方案数。那么令 \(f(i,0/1)\) 表示考虑了前 \(i\) 个人,第 \(i\) 个人选出的球来自前一个人/自己,讨论转移。通过钦定第 \(1\) 个人所选出的球破环求解。复杂度 \(\mathcal O(n)\)。(我没实现所以讲得比较糊 www。
\(\mathcal{Code}\)
只有方法一的代码呢。
/*-Rainybunny-*/
#include <bits/stdc++.h>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
const int MAXN = 1e6, MOD = 998244353, INV2 = 499122177, INV3 = 332748118;
int n, a[MAXN + 5];
inline int mul( const int u, const int v ) { return 1ll * u * v % MOD; }
inline int sub( int u, const int v ) { return ( u -= v ) < 0 ? u + MOD : u; }
inline int add( int u, const int v ) { return ( u += v ) < MOD ? u : u - MOD; }
struct Matrix {
int a, b, c, d;
friend inline Matrix operator * ( const Matrix& u, const Matrix& v ) {
return { add( mul( u.a, v.a ), mul( u.b, v.c ) ),
add( mul( u.a, v.b ), mul( u.b, v.d ) ),
add( mul( u.c, v.a ), mul( u.d, v.c ) ),
add( mul( u.c, v.b ), mul( u.d, v.d ) ) };
}
} pre[MAXN + 5], suf[MAXN + 5];
inline Matrix getTrans( const int i, const bool type ) {
int tmp = mul( mul( a[i], a[i] + 1 ), INV2 );
if ( !type ) {
return { tmp, a[i] + 1,
mul( sub( a[i], mul( add( a[i], a[i] ) + 1, INV3 ) ), tmp ), tmp };
} else {
return { sub( mul( a[i], a[i] ), tmp ), a[i],
mul( sub( a[i], mul( add( a[i], a[i] ) + 1, INV3 ) ), tmp ), tmp };
}
}
int main() {
// freopen( "y.in", "r", stdin );
// freopen( "y.out", "w", stdout );
std::ios::sync_with_stdio( false ), std::cin.tie( 0 );
std::cin >> n;
rep ( i, 1, n ) std::cin >> a[i];
pre[0] = { 1, 0, 0, 1 };
rep ( i, 1, n ) pre[i] = getTrans( i, 1 ) * pre[i - 1];
suf[n + 1] = { 1, 0, 0, 1 };
per ( i, n, 1 ) suf[i] = suf[i + 1] * getTrans( i, 0 );
int ans = 0;
rep ( i, 1, n ) { // i won't give i+1 any ball.
Matrix&& tmp( pre[i - 1] * suf[i + 1] );
ans = add( ans, add( mul( a[i], tmp.a ), tmp.c ) );
}
std::cout << ans << '\n';
return 0;
}
Solution -「ARC 124E」Pass to Next的更多相关文章
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「ARC 101D」「AT4353」Robots and Exits
\(\mathcal{Description}\) Link. 有 \(n\) 个小球,坐标为 \(x_{1..n}\):还有 \(m\) 个洞,坐标为 \(y_{1..m}\),保证上述坐标 ...
- Solution -「ARC 110D」Binomial Coefficient is Fun
\(\mathcal{Description}\) Link. 给定非负整数序列 \(\{a_n\}\),设 \(\{b_n\}\) 是一个非负整数序列且 \(\sum_{i=1}^nb_i\ ...
- Solution -「ARC 126E」Infinite Operations
\(\mathcal{Description}\) Link. 给定序列 \(\{a_n\}\),定义一次操作为: 选择 \(a_i<a_j\),以及一个 \(x\in\mathbb R ...
- Solution -「ARC 126F」Affine Sort
\(\mathcal{Description}\) Link. 给定 \(\{x_n\}\),令 \[f(k)=\left|\{(a,b,c)\mid a,b\in[0,c),c\in[1,k ...
- Solution -「ARC 125F」Tree Degree Subset Sum
\(\mathcal{Description}\) Link. 给定含有 \(n\) 个结点的树,求非负整数对 \((x,y)\) 的数量,满足存在 \(\exist S\subseteq V ...
- Solution -「ARC 125E」Snack
\(\mathcal{Description}\) Link. 把 \(n\) 种零食分给 \(m\) 个人,第 \(i\) 种零食有 \(a_i\) 个:第 \(i\) 个人得到同种零食数量 ...
- Solution -「ARC 058C」「AT 1975」Iroha and Haiku
\(\mathcal{Description}\) Link. 称一个正整数序列为"俳(pái)句",当且仅当序列中存在连续一段和为 \(x\),紧接着连续一段和为 \(y ...
- Solution -「ARC 101E」「AT 4352」Ribbons on Tree
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个点的树,其中 \(2|n\),你需要把这些点两两配对,并把每对点间的路径染色.求使得所有边被染色的方案数 ...
随机推荐
- 如何对K8s进行考核?Kuberhealthy来打个样!
2019年11月,在圣地亚哥KubeCon,我们发布了kuberhealth 2.0.0--将kuberhealthy作为合成监测的Kubernetes operator.这个新功能为开发人员提供了创 ...
- Visaul Studio 2015 MFC 应用程序工程创建
近一段时间开始接触到MFC桌面开发程序,忙完了一段时间的项目开发之后,来整理整理Visaul Studio 2015开发MFC桌面程序的基本功能. 首先从创建软件工程项目开始,Visaul Studi ...
- vscode配置Microsoft C++注意事项
vscode配置c++插件教程链接如下: https://code.visualstudio.com/docs/cpp/config-msvc#_check-your-microsoft-visual ...
- 公司内部一次关于kafka消息队列消费积压故障复盘分享
背景现象 1.20晚上8点业务线开始切换LBS相关流量,在之后的1个小时时间内,积压量呈上升趋势,一路到达50W左右,第二天的图没贴出具体是50W数字,以下是第一天晚上的贴图部分. 现象一: 现象二: ...
- gin源码解读3-gin牛逼的context
Gin封装的最好的地方就是context和对response的处理. github的README的介绍,基本就是对这两个东西的解释. 本篇文章主要解释context的使用方法, 以及其设计原理 为什么 ...
- Go 转义字符及风格
今天来学习一下Go 中的转义字符,源码注释,规范的代码风格以及标准库API 文档; Go 转义字符常用的转义字符有以下几个:1. \t: 表示一个制表符(tab), 通常可以使用它进行排版; 2. \ ...
- Tomcat-给Tomcat添加第三方jar包
给动态web工程添加额外jar包 1,打开项目结构菜单操作界面,添加一个自己的类库 2,添加你当前类库需要的jar包 3,选择你添加的类库,给哪个模块使用 4,选择Artifacts选项,将类库添加到 ...
- 集合框架-HashSet集合(无序唯一)
1 package cn.itcast.p4.hashset.demo; 2 3 import java.util.HashSet; 4 import java.util.Iterator; 5 /* ...
- 集合框架-工具类-Collections-其他方法将非同步集合转成同步集合的方法
集合框架TXT Collections-其他方法将非同步集合转成同步集合的方法
- 3D建模服务提供更高效、专业的3D制作能力,“筑”力开发者
3D建模服务(3D Modeling Kit)是HMS Core在图形图像领域又一技术开放.3D建模产品的定位就是要做快速.简洁.低成本的3D制作能力,并陆续开放给有3D模型.动画游戏制作等能力诉求的 ...