首页 > 其他分享 >ABC259Ex 题解

ABC259Ex 题解

时间:2024-03-05 19:36:38浏览次数:39  
标签:int 题解 inv ABC259Ex 复杂度 Mod ll define

Solution

首先考虑暴力:

  1. 枚举同种颜色的格子,假设两点为 \((i,j),(x,y)\),那么从 \((i,j)\) 到 \((x,y)\) 的方案数即为 \(C_{x-i+y-j}^{x-i}\)。考虑当前颜色有 \(B\) 个,枚举的时间复杂度为 \(O(B^2)\)。

  2. 考虑枚举每一种颜色,算出这种颜色到其他格子方案数,有递推方程:\(f_{i,j}=f_{i-1,j}+f_{i,j-1}\),当 \(a_{i,j}\) 为当前颜色时,\(f_{i,j}=1\)。枚举时间复杂度为 \(O(n^2)\)。

再考虑根号分治,把两个暴力拼在一起,当 \(B \leq n\) 时执行第一种暴力,时间复杂度最坏为 \(O(nB^2)\);当 \(B>n\) 时执行第二种暴力,时间复杂度最坏为 \(O(\frac{n^4}{B})\),当 \(B=n\) 时,总时间复杂度为 \(O(n^3)\)。

注意在处理逆元的时候应处理到 \(2n\),因为需要计算 \(inv_{x-i+y-j}\),而 \(x-i+y-j\) 最大为 \(2n-2\)。

#include<bits/stdc++.h> 
#define ll long long 
#define x first 
#define y second 
#define il inline 
#define debug() puts("-----") 
using namespace std; 
typedef pair<int,int> pii; 
const int N=410; 
const ll Mod=998244353; 
int n; 
ll f[N][N]; 
int a[N][N]; 
vector<pii> v,mp[N*N]; 
ll inv[N<<1],fac[N<<1]; 
il ll qmi(ll x,int k){ 
	ll res=1; 
	while(k){
		if(k&1) res=res*x%Mod; 
		x=x*x%Mod; k>>=1; 
	} return res; 
} 
il ll calc(int i,int j,int x,int y){ 
	int P=x-i+y-j,R=x-i; 
	return fac[P]*inv[P-R]%Mod*inv[R]%Mod; 
} 
il void init(){ 
	fac[0]=inv[0]=1; 
	for(int i=1;i<=2*n;i++) fac[i]=fac[i-1]*i%Mod; 
	inv[2*n]=qmi(fac[2*n],Mod-2); 
	for(int i=2*n-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%Mod; 
} 
signed main(){ 
	scanf("%d",&n); 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			scanf("%d",&a[i][j]); 
			if(!mp[a[i][j]].size()) v.push_back({i,j}); 
			mp[a[i][j]].push_back({i,j}); 
		} 
	} init(); ll ans=0; 
	for(auto u:v){ 
		int col=a[u.x][u.y]; 
		if(mp[col].size()<=n){
			for(auto i:mp[col]) 
				for(auto j:mp[col]) 
					if(i.x<=j.x&&i.y<=j.y) ans=(ans+calc(i.x,i.y,j.x,j.y))%Mod; 
		} else{ 
			for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=0; 
			int col=a[u.x][u.y]; for(auto i:mp[col]) f[i.x][i.y]=1; 
			for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=(f[i][j]+f[i-1][j]+f[i][j-1])%Mod,ans=(ans+((a[i][j]==col)?f[i][j]:0))%Mod; 
		} 
	} printf("%lld\n",ans); return 0; 
} 

标签:int,题解,inv,ABC259Ex,复杂度,Mod,ll,define
From: https://www.cnblogs.com/Celestial-cyan/p/18054720

相关文章

  • CF1800F 题解
    Solution考虑转化题目条件,因为要求字符串恰好有\(25\)个字符,所以考虑枚举没出现过的字符,令其为\(k\)。再令\(f_{i,p}\)表示第\(i\)个字符串\(p\)字符出现次数的奇偶,于是题目条件即为:\(f_{i,k}=f_{j,k}=0\)。\(f_{i,p}+f_{j,p}\bmod2=1\)。于是考虑用一个\(2^{26......
  • CF622F The Sum of the k-th Powers 题解
    原式为\(k+1\)次多项式,所以需要\(k+2\)个点确定。然后转化,前缀和。\[\begin{equation}n=k+2\\\end{equation}\]\[\begin{equation}f(x)=\sum\limits_{i=0}^{n}y_i\prod\limits_{j=0,j\nei}^{n}\frac{x-x_j}{x_i-x_j}\end{equation}\]\[\begin{equation}x_0=......
  • AT_abc331_f [ABC331F] Palindrome Query 题解
    分析线段树。每个节点维护两个值:$s[l\dotsr]$和$s[r\dotsl]$。判断字串是否是回文直接就是询问的答案维护出来的两个值是否相同。首先想到用线段树暴力维护。第一个值很显然是两个儿子的第一个值加起来,第二个值是反着加起来。得到很酷的代码:ilvoidup(intnow){ tr[now......
  • AT_abc287_g [ABC287G] Balance Update Query 题解
    分析一眼分块。用值域分块来维护。先把所有的值离散化,使得至于不大于$n+q$。统计一下每个值的数量,每个块包含值的数量,每个块的价值和。修改值的时候先把原来值的数量,块包含的数量,块的价值剪掉被修改值的贡献,然后在新的值上面更新。修改数量直接改数量的变化贡献即可。找前$x$......
  • P8844 [传智杯 #4 初赛] 小卡与落叶 题解
    分析乱搞题。$1\len,m\le10^5$的时候就可以考虑乱搞了。发现每次操作$1$都会把上一次的操作$1$覆盖掉,那么第$i$个询问时树的颜色情况就是由前$1$个操作$1$决定。也就是说这个询问的内容变成了:在$x$为根的子树中,深度不小于$x'$的节点数量。$x'$是该操作$1$......
  • AT_abc287_g [ABC287G] Balance Update Query 题解2
    分析权值线段树。给每个节点赋一个值$val$和$a_i=val$的$b_i$之和。修改$a_x$的时候先将$a_x$的出现次数在树上剪掉$b_x$,再在$y$上面加上;修改$b_x$的时候直接加上变化量$y-b_x$。由于我们是要取前$x$大的$a_i$之和,在询问的时候有限考虑右儿子,然后在是当前......
  • AT_abc335_f [ABC335F] Hop Sugoroku 题解
    比E简单。分析考虑暴力DP。定义状态函数$f_i$表示最后一个黑点为$i$时的方案数,有:$f_i=\sum\limits_{j=1}^{i-1}f_j[(i-j)\bmodval_j=0]$。不难发现在使用刷表法的时候,转移代码:for(reintj=1;i+val[i]*j<=n;++j)f[i+val[i]*j]=(f[i+val[i]*j]+f[i])%p;这玩意复杂......
  • AT_abc190_e [ABC190E] Magical Ornament 题解
    分析考虑状压。定义状态函数$f_{i,j}$表示在得到$C$出现过的状态为$i$且排列末尾为$j$时的最小代价。则有转移方程:$f_{i,j}=\min{f_{i',k}+dis_{k,j}}$,保证$i'$表示集合属于$i$。$dis_{i,j}$跑最短路就行了,通过枚举$C_i$为起点可以做到$O(kn\logn)$的复杂度求......
  • CF1800F Dasha and Nightmares 题解
    分析考虑枚举。注意到第二个条件是必须要有$25$个字符在里面出现过,故考虑枚举唯一没出现过的字符$k$,然后再枚举$s_i$。令$cnt_{i,j}$表示$s_i$中字符$c$出现的奇偶性。如果有字符$c\nek\landcnt_{i,c}=0$,则在$s_j$中必有$cnt_{j,c}=1$;反之同理。枚举字符$c......
  • P5655 基础数论函数练习题 题解
    分析考虑莫队。令$S=\operatorname{lcm}(a_l,a_{l+1},a_{l+2},\dots,a_{r-1})$。则对于新加进来的$a_r$,有:$$\operatorname{lcm}(a_l,a_{l+1},a_{l+2},\dots,a_{r-1},a_r)\=\operatorname{lcm}(S,a_r)\=\frac{S\timesa_r}{\gcd(S,a_r)}$$很容易发现,$S$在不取模的情况下会......