Live2D

Solution -「ZJOI 2016」「洛谷 P3352」线段树

Descrtiption

  给定 {an},现进行 m 次操作,每次操作随机一个区间 [l,r],令其中元素全部变为区间最大值。对于每个 i,求所有可能操作方案最终得到的 ai 之和。答案模 (109+7)

  n,q400

Solution

  那什么我懒得写题解了就把草稿贴上来好了。(

f(i,l,r,x):=the operating ways that after i-th operation,i[l,r],aix and al1,ar+1>x.f(i,l,r,x)=((l2)+(rl+22)+(nr+12))f(i1,l,r,x)+p<l(p1)f(i1,p,r,x)+r<p(np)f(i1,l,p,x).Thus, the answer for i can be represented as ri, whereri=xx[l,r]if(q,l,r,x)f(q,l,r,x1)=[l,r]ixf(q,l,r,x)=[l,r]ig(q,l,r)    (g(i,l,r):=xf(i,l,r,x)).Obviously, g's expression is similar to f's.Maintaining partial sum, this problem can be solved in O(qn2).

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 = 400, MOD = 1e9 + 7, IINF = 0x3f3f3f3f;
int n, m, a[MAXN + 5];
int g[2][MAXN + 5][MAXN + 5], sum[MAXN + 5];

inline int tot( const int u ) { return ( u * ( u + 1ll ) >> 1 ) % MOD; }
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; }

int main() {
	scanf( "%d %d", &n, &m );
	rep ( i, 1, n ) scanf( "%d", &a[i] );
	a[0] = a[n + 1] = IINF;
	
	rep ( l, 1, n ) {
		int mxv = a[l];
		rep ( r, l, n ) {
			mxv = mxv < a[r] ? a[r] : mxv;
			int mnv = a[l - 1] < a[r + 1] ? a[l - 1] : a[r + 1];
			if ( mnv > mxv ) g[0][l][r] = sub( mxv, mnv < IINF ? mnv : 0 );
		}
	}
	
	for ( int sta = 1, i = 1; i <= m; sta ^= 1, ++i ) {
		memset( sum, 0, sizeof sum );
		rep ( l, 1, n ) rep ( r, l, n ) {
			g[sta][l][r] = add( sum[r], mul( add( add( tot( l - 1 ),
			  tot( r - l + 1 ) ), tot( n - r ) ), g[!sta][l][r] ) );
			sum[r] = add( sum[r], mul( l - 1, g[!sta][l][r] ) );
		}
		memset( sum, 0, sizeof sum );
		per ( r, n, 1 ) per ( l, r, 1 ) {
			g[sta][l][r] = add( g[sta][l][r], sum[l] );
			sum[l] = add( sum[l], mul( n - r, g[!sta][l][r] ) );
		}
	}
	
	rep ( i, 1, n ) {
		int ans = 0;
		rep ( l, 1, i ) rep ( r, i, n ) ans = add( ans, g[m & 1][l][r] );
		printf( "%d%c", ans, i < n ? ' ' : '\n' );
	}
	return 0;
}

posted @   Rainybunny  阅读(51)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
历史上的今天:
2020-09-26 Solution -「CF 1392G」Omkar and Pies
点击右上角即可分享
微信分享提示