題解:CF2125E Sets of Complementary Sums
題目:
問 \(m\)(\(m\) 任取)個正整數(shù)組成的 \(a\) 數(shù)組按照題目操作可構(gòu)造的長度為 \(n\) 值域為 \([1,x]\) 的集合數(shù)量。
題目操作為:\(s=\sum_{i=1}^m a_i\),把 \(s-a_i\) 插入集合。
推點性質(zhì)
1
集合有無序性,令集合內(nèi)升序排序,可以代表這個集合。
\(a\) 也有無序性,所以也升序排序。(具體的 \(a_i\le a_{i+1}\))
2
考慮增量:
如果新加入的 \(a_i\) 之前出現(xiàn)過,則不會增加集合元素,只會讓集合整體加 \(a_i\)。
如果沒出現(xiàn)過,則會讓集合整體加 \(a_i\) 后加入 \((\sum_{j=1}^i a_j) -a_i\)。
3
首先看到 \(s-a_i\) 容易想到差分,發(fā)現(xiàn):
若 \(a\) 不重,那么 \(a\) 的差分數(shù)組和集合的差分數(shù)組是一樣的。
若 \(a\) 有重,\(a\) 去完重后的差分數(shù)組和集合的差分數(shù)組還是一樣的,因為重的 \(a_i\) 只會影響 \(s\)。所以下面我們均維護去重后的 \(a\),而重復(fù)的 \(a_i\) 會體現(xiàn)為全局加。
4
構(gòu)造 \(a_1=1\) 的 \(a\),集合最大值為 \(s-1\),對應(yīng)的合法原數(shù)組數(shù)量為 \(x-(s-1)+1\)。(同時也可知 \(s\le x+1\) 的范圍。)
于是有個暴力 DP:
\(f_{i,j,k}\):構(gòu)造 \(a_1=1,\left | a \right |=i,s=j,a_i=k\) 的方案數(shù)。
轉(zhuǎn)移 \(O(nx^3)\)。(實際上判掉無解是 \(O(\sqrt x x^3)\))
5
思考如何優(yōu)化性質(zhì) \(4\) 的 DP,考慮去掉 \(k\) 這一維,我們定義兩種操作:
- 在 \(a\) 序列前拼接 \(1\),
- \(a\) 序列整體 \(+1\)。
我們發(fā)現(xiàn)這樣很好維護遞增的條件了,并且我們也不用枚舉新拼接的數(shù),因為我們可以類似完全背包地考慮到每個新拼接的數(shù)。
\(f_{i,j,0/1}\):\(\left | a \right | =i,s=j\),\(a_1\) 是否是 \(1\)。
6
由于 \(s\le x+1\) 且我們 DP 的是無重復(fù)元素的 \(a\),所以 \(\frac{(1+n)n}{2}\le x+1\) 時,\(f_n\) 才會有值。
判完無解復(fù)雜度為 \(O(\sqrt x x)\)。
代碼:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int read()
{
int x=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x;
}
void xie(int x,int shen=0)
{
if(!x)
{
if(!shen) putchar('0');
return ;
}
xie(x/10,1);
putchar('0'+x%10);
}
const int QAQ=2e5+7,mo=998244353;
int t,n,x,dp[QAQ][2];
signed main()
{
t=read();
for(int i1=1;i1<=t;i1++)
{
n=read(),x=read();
if(n==1) {xie(x),putchar('\n');continue;}
if(n*(n-1)/2>x+1) {puts("0");continue;}
for(int i=0;i<=x+1;i++) dp[i][0]=dp[i][1]=0;
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=x+1;j++) dp[j][1]=dp[j-1][0];
for(int j=0;j<=x+1;j++)
if(j<i) dp[j][0]=0;
else dp[j][0]=(dp[j-i][0]+dp[j-i][1])%mo;
}
int ans=0;
for(int i=1;i<=x+1;i++) ans=(ans+dp[i][1]*(x-i+2)%mo)%mo;
xie(ans);
putchar('\n');
}
return 0;
}

浙公網(wǎng)安備 33010602011771號