首页 > 其他分享 >LG P9108 [PA2020] Malowanie płotu

LG P9108 [PA2020] Malowanie płotu

时间:2024-09-03 15:40:23浏览次数:5  
标签:LG ch int sum p1 PA2020 aligned buf otu

状态数是 \(O(nm^2)\) 的DP很好想,就是 \(dp_{i,l,r}\) 表示第 \(i\) 次的区间为 \([l,r]\) 的方案数。

但是这个状态数就已经死了,而题目又提示 \(n\times m \leq 1e7\) ,说明状态只能形如 \(dp_{i,j}\)。

这时就会想到一个简陋的打补丁方式:设 \(f_{i,l},g_{i,r}\) 分别表示第 \(i\) 次以 \(l\) 为左端点的所有区间的方案数,以 \(r\) 为右端点的所有区间的方案数。

因为 \(f,g\) 本质相同,所以下面都只关注 \(f\)。

设第 \(i\) 个区间为 \([l,r]\),第 \(i-1\) 个为 \([l',r']\)。那么两者相交的话,有以下四种情况。

方便表述,起个简称:包含,左交,右交,被包含(主语是第 \(i\) 个区间)。

我们希望求出 \(f_{i,l}\),那么先暴力地转移。那么枚举右端点 \(r\),对于1,2种,直接 \(f_{i-1,l\textcolor{red}<l'\leq r} \to f_{i,l}\)。

那么3,4种呢?如果仿照刚刚直接把右端点 \(\geq r\) 的 \(g_{i-1}\) 全部加入,那么会有些区间算重复。

观察3,4有没有1,2没有的性质用来转移?是的,他们都与 \([l,r]\) 区间的左端点有交。

故我们再开一个数组 \(h_{i,j}\),表示第 \(i\) 个区间经过 \(j\) 的方案数。\(h_{i-1,l}\to f_{i,l}\) 就行啦(这也是为什么刚刚使用小于号的原因)。

注意我们现在只列出了暴力转移的方程,推推式子前缀和优化就行了。

\[\begin{aligned} f_{i,l} & = \sum_{r=l}^{n} h_{i-1,l}+f_{i-1,l<l'\leq r} \\ & = (n-l+1)h_{i-1,l}+\sum_{r=l}^{n}Sf_{i-1,r}-Sf{i-1,l} \\ & = (n-l+1)h_{i-1,l}+\sum_{r=l}^{n}Sf_{i-1,r}-(n-l+1)Sf_{i-1,l} \end{aligned} \]

\[\begin{aligned} g_{i,r}&=\sum_{l=1}^{r}h_{i-1,r}+g_{i-1,l\leq r' < r} \\ & = r\times h_{i-1,r} + \sum_{l=1}^{r} Sg_{i-1,r-1}-Sg_{i-1,l-1} \\ & = r\times h_{i-1,r} + r \times Sg_{i-1,r-1} - \sum_{l=1}^{r} Sg_{i-1,l-1} \end{aligned} \]

\[tot=\sum_{l=1}^n f_{i,l} \\ \begin{aligned} h_{i,j}=tot-\sum_{r<j}g_{i,r}-\sum_{l>j}f_{i,l} \end{aligned} \]

\(S_f,S_g\) 表示一次前缀和,还要用二次前缀和优化。

#include <bits/stdc++.h>

using namespace std;

int P;
inline int Add(int x , int y){return x + y < P ? x + y : x + y - P;}
inline int Sub(int x , int y){return x < y ? x + P - y : x - y;}
inline int Mul(int x , int y){return 1LL * x * y % P;}

using IO_t=int;inline char gc(){static char buf[100000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline IO_t read(){IO_t x=0;bool f=0;char ch=gc();while(!isdigit(ch)){f|=(ch=='-');ch=gc();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=gc();}return(f?-x:x);}

int n , m;

signed main(){
//	freopen("a.in" , "r" , stdin);
//	freopen("a.out" , "w" , stdout);
	
	n = read() , m = read() , P = read();
	
	int f[n + 1][m + 1] , g[n + 1][m + 1] , h[n + 1][m + 1];
	int F[n + 1][m + 1] , G[n + 1][m + 1];
	memset(f , 0 , sizeof f);
	memset(g , 0 , sizeof g);
	memset(h , 0 , sizeof h);
	memset(F , 0 , sizeof F);
	memset(G , 0 , sizeof G);
	
	for(int l = 1; l <= m; ++ l){
		f[1][l] = m - l + 1;
	}
	for(int r = 1; r <= m; ++ r){
		g[1][r] = r;
	}
	for(int j = 1; j <= m; ++ j){
		h[1][j] = Mul(j , m - j + 1);
	}
	for(int j = 1; j <= m; ++ j){
		f[1][j] = Add(f[1][j] , f[1][j - 1]);
		g[1][j] = Add(g[1][j] , g[1][j - 1]);
	}
	int tot = f[1][m];
	for(int j = 1; j <= m; ++ j){
		int tmp1 = g[1][j - 1];
		int tmp2 = Sub(f[1][m] , f[1][j]);
		h[1][j] = Sub(Sub(tot , tmp1) , tmp2);
	}
	for(int j = 1; j <= m; ++ j){
		F[1][j] = Add(f[1][j] , F[1][j - 1]);
		G[1][j] = Add(g[1][j] , G[1][j - 1]);
	}
	
	for(int i = 2; i <= n; ++ i){//f,g用完后变为前缀和
		//F,G为前缀和的前缀和
		for(int l = 1; l <= m; ++ l){
			int tmp1 = Mul(m - l + 1 , h[i - 1][l]);
			int tmp2 = Sub(F[i - 1][m] , F[i - 1][l - 1]);
			int tmp3 = Mul(m - l + 1 , f[i - 1][l]);
			f[i][l] = Add(tmp1 , Sub(tmp2 , tmp3));
		}
		for(int r = 1; r <= m; ++ r){
			int tmp1 = Mul(r , h[i - 1][r]);
			int tmp2 = Mul(r , g[i - 1][r - 1]);
			int tmp3 = Sub(G[i - 1][r - 1] , G[i - 1][0]);
			g[i][r] = Add(tmp1 , Sub(tmp2 , tmp3));
		}
		for(int j = 1; j <= m; ++ j){
			f[i][j] = Add(f[i][j] , f[i][j - 1]);
			g[i][j] = Add(g[i][j] , g[i][j - 1]);
		}
		int tot = f[i][m];
		for(int j = 1; j <= m; ++ j){
			int tmp1 = g[i][j - 1];
			int tmp2 = Sub(f[i][m] , f[i][j]);
			h[i][j] = Sub(Sub(tot , tmp1) , tmp2);
		}
		for(int j = 1; j <= m; ++ j){
			F[i][j] = Add(f[i][j] , F[i][j - 1]);
			G[i][j] = Add(g[i][j] , G[i][j - 1]);
		}
	}
	
//	assert(f[n][m] == g[n][m]);
	printf("%d" , g[n][m]);
	
	return 0;
}

标签:LG,ch,int,sum,p1,PA2020,aligned,buf,otu
From: https://www.cnblogs.com/TongKa/p/18394697

相关文章

  • P9108 [PA2020] Malowanie płotu
    题意:给定\(n,m\),一个区间序列\(\{[L_1,R_1],[L_2,R_2],\cdots,[L_n,R_n]\}\)被称为好的当且仅当:\(\foralli\in[1,n],1\leL_i\leR_i\lem\)。\(\foralli\in[1,n-1],[L_i,R_i]\cup[L_{i+1},R_{i+1}]\ne\emptyset\)。输出好的序列个数对给定质数\(p\)......
  • Study Plan For Algorithms - Part20
    1.树的子结构输入两棵二叉树A和B,判断B是不是A的子结构。方法一:classTreeNode:def__init__(self,val=0,left=None,right=None):self.val=valself.left=leftself.right=rightdefisSubStructure(A,B):ifnotAornot......
  • Goolge earth studio 高阶1——缓动设置需求
    缓动设置能够控制动画在两个关键帧之间的移动方式,使运动更加动态和自然。1、创建新项目首先,创建一个快速示例项目,命名为“Easing”,导航到东京的新宿地区,那里有非常好的3D数据。相机定位好,使建筑物位于右侧,公园位于左侧。为了清楚地看到缓动如何影响运动,我们将只关注一个属......
  • Study Plan For Algorithms - Part18
    1.搜索插入位置题目链接:https://leetcode.cn/problems/search-insert-position/给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。classSolution:defsearchInsert(self,nums:List[int],target:......
  • COMP20003 Algorithms and Data Structures Spellcheck Lookup
    Assignment2:SpellcheckLookupGeneralYoumustreadfullyandcarefullytheassignmentspecificationandinstructions.Course:COMP20003AlgorithmsandDataStructures@Semester2,2024DeadlineSubmission:Friday6thSeptember2024@11:59pm(endo......
  • C++头文件<algorithm>中常用函数简介
     概述头文件algorithm(算法库)中主要提供了一些对容器操作的函数,如排序、搜索、复制、比较等,因此使用频率还是很高的,由于主要是操作容器,所以函数的语法也很类似:algorithm_name(container.begin(),container.end(),...);其中,container.begin()和container.end()分......
  • lg-soar:助力开发者腾飞的利器
    在开发的世界里,我们总是追求速度与效率。“lg-soar”就像开发者的翅膀,助你轻松起飞,翱翔于云端。今天,让我们一起深入探索这个平台的独特魅力,以及如何迅速掌握其使用技巧。平台概览“lg-soar”是一个全开放源码、高速度及高效率的开发平台。它不仅易于使用,而且具有极高的灵......
  • Goolge earth studio 进阶4——路径修改与平滑
    如果我们希望在大约中途时获得更多的城市鸟瞰视角。可以将相机拖动到这里并创建一个新的关键帧。camera_target_clip_7EarthStudio会自动平滑我们的路径,所以当我们通过这个关键帧时,不是一个生硬的角度,而是一个平滑的曲线。camera_target_clip_8路径上有贝塞尔控制......
  • Study Plan For Algorithms - Part16
    1.下一个排列题目链接:https://leetcode.cn/problems/next-permutation/整数数组的一个排列就是将其所有成员以序列或线性顺序排列。整数数组的下一个排列是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组......
  • yum依赖python2环境-"No module named urlgrabber"
    1.python3安装perl环境以及IPC/cmd.pm模块,由于环境中安装了pyhon2和python3导致模块引入冲突。makepython3时一直报错没有Module_tktinter,重新安装tk后python3还是import失败 2.检查发现python2可以引入,并且再进行安装模块时,使用的是python,而系统python指向python2 3.修改......