首页 > 其他分享 >[CF1158F]Density of subarrays

[CF1158F]Density of subarrays

时间:2023-10-10 16:36:08浏览次数:42  
标签:cnt CF1158F 颜色 包含 Density subarrays vector 序列 sim

F - Density of subarrays

屲,平衡复杂度题

首先考虑如何求一个序列的密度

从最左端开始,找到需序列\(A[1...n]\)的最小段\(A[1...a_1]\),使其包含\(1\sim c\)的所有颜色,然后又以\(a_1+1\)为起点,找下一个最短的包含\(1\sim c\)的所有颜色的段,最后找到的这样的段的个数就是这个序列的密度

由此也可得,一个长度为\(n\)的序列,密度最大为\(\frac nc\)

所以,就有一个显然的状压\(dp\):设\(f[i][j][S]\)表示前\(i\)个中,已有了\(j\)个包含\(1\sim c\)的所有颜色的段,目前最后一个段包含颜色的状态为\(S\)的序列的个数,则有:

\[f[i][j][s]\rightarrow \left\{ \begin{aligned} &f[i+1][j][s|(1<<a[i+1]-1)](s|(1<<a[i+1]-1)未满)\\ &f[i+1][j+1]][0](s|(1<<a[i+1]-1)已满) \end{aligned} \right. \]

复杂度就是\(O(\frac{n^2}c\times2^c)\)

然后这个复杂度在\(c\)更大时就\(G\)了,所以考虑不用状压的另一种\(dp\)

注:下文中\(A[i]\)仅仅代表\(i\)在序列中的存在形式,若在值上\(A[j]=A[i]\),那么在下文中\(A[j]\)也不等同\(A[i]\)

设\(f[i][j]\)表示以\(A[i]\)结尾的序列中,恰有\(j\)个包含\(1\sim c\)的所有颜色的序列的数量,考虑如何转移

设\(g[i][j]\)表示\(A[i,j]\)中,包含\(A[j]\),且包含\(A[j]\)后恰好包含\(1\sim c\)的所有颜色的序列的数量,那么有

\[f[k][j+1]+=f[i][j]\times g[i+1][k] \]

又设\(h[i][j]\)表示\(A[i,j]\)中,包含\(A[j]\)且不包含\(1\sim c\)的所有颜色的序列的数量

那么最后的答案就为:

\[\sum \sum f[i][j]\times (h[i+1][i+1...n]+i>0) \]

最后的那个\(i>0\)表示\([i+1,n]\)里不选任何序列来接到\(f[i][j]\)后面,显然,当\(i=0\)时,\(f[i][j]\)就已经是空的了,所以若\(i=0\)时也不选,那么空的序列就会被计入答案,这是不合法的

那么\(g[i][j]\)和\(h[i][j]\),可以枚举\(j\),然后\(i\)从后往前枚举计算

若目前\([i,j]\)里不存在序列包含\(1\sim c\)的所有颜色,那么此时\(g[i][j]=0,h[i][j]=2^{j-i}\)

因为\(A[j]\)是必须选的

若包含\(1\sim c\)的所有颜色,那么\(g[i][j]=\prod_{1\leq k\leq c\&\&k\neq A[j]}(2^{cnt_k}-1)\),\(h[i][j]=2^{j-i}-2^{cnt_{A[j]}-1}\times\prod_{1\leq k\leq c\&\&k\neq A[j]}(2^{cnt_k}-1)\)

其中,\(cnt_k\)表示颜色\(k\)在\([i,j]\)中出现了\(cnt_k\)次

复杂度为\(O(\frac{N^3}c)\)

然后结合这两种做法,就可以过了

#include<bits/stdc++.h>
using namespace std;
const int N=3005,MOD=998244353;
int n,c,a[N],ans[N];
void add(int &a,int b){ 
	a+=b; 
	if(a>=MOD) a-=MOD; 
}
void work1(){
	vector<vector<vector<int>>> f(2,vector<vector<int>>(n/c+1,vector<int>(1<<c,0)));
	f[0][0][0]=1; int id=0,mx=(1<<c)-1;
	for(int i=1;i<=n;++i,id^=1){
		for(int j=0;j<=i/c;++j) for(int s=0;s<=mx;++s) f[id^1][j][s]=f[id][j][s];
		for(int j=0;j<=(i-1)/c;++j)
			for(int s=0;s<mx;++s){
				if(!f[id][j][s]) continue;
				int nows=s|(1<<a[i]-1),nowj=j;
				if(nows==mx) nows=0,++nowj;
				add(f[id^1][nowj][nows],f[id][j][s]);
			}
	}
	for(int i=0;i<=n/c;++i) for(int s=0;s<=mx;++s) add(ans[i],f[id][i][s]);
	add(ans[0],MOD-1);//-empty 
}
int cnt[N],sur,p2[N],inv[N],use;
void ad(int x){
	if(!cnt[x]) ++cnt[x],--sur;	
	else{
		use=1ll*use*inv[cnt[x]]%MOD;
		++cnt[x];
		use=1ll*use*(p2[cnt[x]]-1<0?p2[cnt[x]]-1+MOD:p2[cnt[x]]-1)%MOD;
	}
}
void Init(){
	for(int i=1;i<=c;++i) cnt[i]=0;
	sur=c,use=1;
}
int power(int x,int y){
	if(x<0) x+=MOD;
	int ans=1;
	for(;y;y>>=1,x=1ll*x*x%MOD) if(y&1) ans=1ll*ans*x%MOD;
	return ans; 
}
void work2(){
	vector<vector<int>> g(n+5,vector<int>(n+5,0)),h(n+5,vector<int>(n+5,0)),f(n+5,vector<int>(n+5,0));
	vector<int> sum(n+5,0);
	p2[0]=use=1;
	for(int i=1;i<=n;++i) p2[i]=2ll*p2[i-1]%MOD;
	for(int i=1;i<=n;++i) inv[i]=power(p2[i]-1,MOD-2);
	for(int j=1;j<=n;++j,Init())
		for(int i=j;i;--i){
			ad(a[i]);
			if(sur) h[i][j]=p2[j-i];
			else{
				int v=1ll*use*inv[cnt[a[j]]]%MOD;
				g[i][j]=v,h[i][j]=((1ll*p2[j-i]-1ll*v*p2[cnt[a[j]]-1]%MOD)%MOD+MOD)%MOD; 
			}
		}
	f[0][0]=1;
	for(int i=0;i<n;++i)
		for(int j=0;j<=i/c;++j)
			if(f[i][j])
				for(int k=i+1;k<=n;++k) f[k][j+1]=(1ll*f[k][j+1]+1ll*f[i][j]*g[i+1][k]%MOD)%MOD;
	for(int i=0;i<=n;++i) for(int j=i;j<=n;++j) add(sum[i],h[i][j]);
	for(int i=0;i<=n;++i)
		for(int j=0;j<=i/c;++j){
			if(i) add(ans[j],f[i][j]);//[i+1,n]=empty
			add(ans[j],1ll*f[i][j]*sum[i+1]%MOD);
		}
}
int main(){
	scanf("%d%d",&n,&c);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]);
	if(c<=10) work1();
	else work2();
	for(int i=0;i<=n;++i) printf("%d ",ans[i]);
 
	return 0;
}

标签:cnt,CF1158F,颜色,包含,Density,subarrays,vector,序列,sim
From: https://www.cnblogs.com/LuoyuSitfitw/p/17755029.html

相关文章

  • [CF1158F] Density of subarrays
    Let$c$besomepositiveinteger.Let'scallanarray$a_1,a_2,\ldots,a_n$ofpositiveintegers$c$-array,ifforall$i$condition$1\leqa_i\leqc$issatisfied.Let'scall$c$-array$b_1,b_2,\ldots,b_k$asubarray......
  • 什么是前端开发领域中的屏幕像素密度 Pixel Density
    当谈论到前端开发中的像素密度(PixelDensity),实际上是在讨论设备屏幕的像素密度,也称为像素密度或PPI(PixelsPerInch)。像素密度是指屏幕上每英寸(2.54厘米)所包含的像素数量。它是一个重要的概念,因为不同的设备在相同尺寸的屏幕上可能拥有不同的像素密度,从而影响显示效果和图像质量。......
  • [LeetCode] 2461. Maximum Sum of Distinct Subarrays With Length K
    Youaregivenanintegerarray nums andaninteger k.Findthemaximumsubarraysumofallthesubarraysof nums thatmeetthefollowingconditions:Thelengthofthesubarrayis k,andAlltheelementsofthesubarrayare distinct.Return themaxim......
  • Density estimation using Real NVP
    目录概MotivationRealNVPCouplinglayersDinhL,Sohl-DicksteinJ.andBengioS.Densityestimationusingrealnvp.ICLR,2017.概一种可逆的flow,感觉很diffusion已经非常非常像了.果然,伟大的成果从来不是一蹴而就的.Motivation\(x\)是原始数据,\(z\)......
  • [LeetCode] 2348. Number of Zero-Filled Subarrays
    Givenanintegerarray nums,return thenumberof subarrays filledwith 0.A subarray isacontiguousnon-emptysequenceofelementswithinanarray.Ex......
  • LC 2447. Number of Subarrays With GCD Equal to K
    2447.NumberofSubarraysWithGCDEqualtoK思路与题解最大公约数,Euclideanalgorithms算法证明:如果我们有2个数:\(a\)和\(b\),不妨假设\(a>b\),当不能整除的情......
  • E. Beautiful Subarrays(01字典树)
    Problem-E-Codeforces题意:给一个长度为n的数组a,问有多少个连续的子数组的异或和大于等于k思路:01字典树建立前缀异或和数组,题目变为有多少个$a_iˆa_j(1......
  • Even Subarrays(数论问题)
    题目链接题目描述:Youaregivenanintegerarray\(a_1,a_2,…,a_n(1≤a_i≤n).\)FindthenumberofsubarraysofawhoseXORhasanevennumberofdivisors.In......
  •   Codeforces Round #841 (Div. 2) and Divide by Zero 2022 -----C. Even Subarray
    题目链接:https://codeforces.com/contest/1731/problem/C  题目的大致意思是:给长度为n的数组,求 子数组的异或和  的结果的除数个数为偶数个的子数组有多......
  • C. Even Subarrays
    CodeforcesRound#841(Div.2)andDividebyZero2022题目大意给定一个数组,求满足所有元素异或的结果有偶数个因子的子数组的个数。本题将0视作有奇数个因子。解题......