ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

「PER #2」2048

2022-05-08 20:02:14  阅读:189  来源: 互联网

标签:const 前缀 int su 2048 PER AddEq mod


题目

点这里看题目。

Public Judge 是新出来的 OJ,所以可能认不得。

不过没关系,根据 p_b_p_b 的说法,上面的题基本上都是搬的

分析

首先,可以忽略每次加入的“位置”,因为我们始终可以保证所有的数都排在前缀上。

其次,我们注意到,如果新来的数大于当前最靠后的那个数,则最终效果是原有前缀全部被丢弃;否则,我们如果保证新来的数总是小于等于最靠后的那个数,则最终效果是进行二进制的累加

所以,对于当前的一个活跃(即会影响累加结果)的前缀而言,它一定是单调递减的。这样的话,只要不进位,我们可以认为已有的数对于之后的数没有后效性。根据这个性质,我们可以将这个前缀的形成过程,看作是每次经过若干步,在这个前缀的末尾加入了一个新的数

那么,首先考虑一个数出现的概率。由于没有步数限制,我们只需要记录 \(f_{i,j}\),表示长度为 \(i\) 的序列中,经过若干步,在头部产生一个 \(2^j\) 的概率。容易得到它的转移方程:

\[f_{i,j}=[j \le m]p_{j+1}+f_{i,j-1}f_{i-1,j-1} \]

转移的逻辑是,要么是直接生成 \(2^j\),要么先后生成两个 \(2^{j-1}\)(后面的生成过程不会受前面的那个影响),最后再合并。

而后,利用期望的线性性拆开贡献,则我们只需要考虑某个前缀的出现概率,直接一边构造前缀形态一边 DP。设 \(g_{i,j}\) 表示经过若干步后,生成一个长度为 \(i\) 的前缀,以 \(2^j\) 结尾的概率。倒腾一下也可以得到转移方程:

\[g_{i,j}=\sum_{k>j}g_{i-1,k}f_{n-i+1,j}+\sum_{k<j}g_{i-1,k}\prod_{s=k+1}^jp_s\prod_{t=s}^{j-1}f_{n-i,t} \]

转移逻辑是,分类讨论前缀 \([1,i-1]\):

  1. 如果 \(i-1\) 上的数大于 \(2^j\),则前缀 \([1,i-1]\) 不会影响第 \(i\) 个数的产生,直接用 \(f\) 计算;

  2. 如果 \(i-1\) 上的数小于 \(2^j\),根据之前的分析,第 \(i\) 个数的初始值 \(2^s\) 必须大于第 \(i-1\) 个,才能让前缀 \([1,i-1]\) 失效;之后,还需要从小到大产生若干个数,来将 \(2^s\) 提升到 \(2^j\)。

    这一部分其实比较类似于限制第一个数的 \(f\) 的转移。

朴素转移为 \(O(n^3)\),不难优化到 \(O(n^2)\)。

小结:

  1. 这道题提供了一个基础思路:操作过程比较复杂的模型,可以将连续的操作过程拆分成若干个步骤来考虑

  2. 另外一方面,既然操作过程很复杂,也应该抓住较为简洁的“生成的前缀”这一部分来考虑。

代码

#include <cstdio>

#define rep( i, a, b ) for( int i = (a) ; i <= (b) ; i ++ )
#define per( i, a, b ) for( int i = (a) ; i >= (b) ; i -- )

const int mod = 998244353;
const int MAXN = 4005;

template<typename _T>
void read( _T &x ) {
	x = 0; char s = getchar(); bool f = false;
	while( ! ( '0' <= s && s <= '9' ) ) { f = s == '-', s = getchar(); }
	while( '0' <= s && s <= '9' ) { x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar(); }
	if( f ) x = -x;
}

template<typename _T>
void write( _T x ) {
	if( x < 0 ) putchar( '-' ), x = -x;
	if( 9 < x ) write( x / 10 );
	putchar( x % 10 + '0' );
}

int f[MAXN][MAXN], g[MAXN][MAXN];

int pw[MAXN];
int P[MAXN];

int N, M;

inline int Qkpow( int, int );
inline int Inv( const int &a ) { return Qkpow( a, mod - 2 ); }
inline int Mul( int x, const int &v ) { return 1ll * x * v % mod; }
inline int Sub( int x, const int &v ) { return ( x -= v ) < 0 ? x + mod : x; }
inline int Add( int x, const int &v ) { return ( x += v ) >= mod ? x - mod : x; }

inline int& MulEq( int &x, const int &v ) { return x = 1ll * x * v % mod; }
inline int& SubEq( int &x, const int &v ) { return ( x -= v ) < 0 ? ( x += mod ) : x; }
inline int& AddEq( int &x, const int &v ) { return ( x += v ) >= mod ? ( x -= mod ) : x; }

inline int Qkpow( int base, int indx ) {
	int ret = 1;
	while( indx ) {
		if( indx & 1 ) MulEq( ret, base );
		MulEq( base, base ), indx >>= 1;
	}
	return ret;
}

int main() {
	int su = 0;
	read( N ), read( M );
	rep( i, 0, M - 1 ) read( P[i] ), AddEq( su, P[i] );
	su = Inv( su );
	rep( i, 0, M - 1 ) MulEq( P[i], su );
	rep( i, 1, N ) rep( j, 0, N + M ) {
		if( j < M ) f[i][j] = P[j];
		if( j > 0 ) AddEq( f[i][j], Mul( f[i][j - 1], f[i - 1][j - 1] ) );
	}
	int ans = 0; g[0][N + M] = 1;
	pw[0] = 1; rep( i, 1, N + M + 1 ) pw[i] = Mul( pw[i - 1], 2 );
	rep( i, 1, N ) {
		int su = 0, contri = 0;
		per( j, N + M, 0 ) {
			AddEq( g[i][j], Mul( su, f[N - i + 1][j] ) );
			AddEq( su, g[i - 1][j] );
		}
		su = g[i - 1][0];
		rep( j, 1, N + M ) {
			MulEq( contri, f[N - i][j - 1] );
			AddEq( contri, Mul( su, P[j] ) );
			AddEq( g[i][j], contri );
			AddEq( su, g[i - 1][j] );
		}
		rep( j, 0, N + M )
			AddEq( ans, Mul( g[i][j], Mul( f[N - i][j], pw[j + 1] ) ) );
	}
	write( ans ), putchar( '\n' );
	return 0;
}

标签:const,前缀,int,su,2048,PER,AddEq,mod
来源: https://www.cnblogs.com/crashed/p/16246616.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有