HDU 5230
题意:给出n,L,R 问[1,2...n-1]中和为[L,R]的方案数.每个数只能选一次. n,L,R<=1e5.
求L<=x<=R 的拆分数
每个加数都不同 . (1+2+..i)<=n i<=sqrt(n) 加数个数最多根号n个.
dp[i][j] 把j拆分成i个不同加数的方法数.
i个加数中有一个是1,i个加数一个1都没有
题意:给出n,L,R 问[1,2...n-1]中和为[L,R]的方案数.每个数只能选一次. n,L,R<=1e5.
求L<=x<=R 的拆分数
每个加数都不同 . (1+2+..i)<=n i<=sqrt(n) 加数个数最多根号n个.
dp[i][j] 把j拆分成i个不同加数的方法数.
i个加数中有一个是1,i个加数一个1都没有
dp[i][j]=dp[i-1][j-i]+dp[i][j-i].
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+20,M=320,mod=998244353;
ll dp[2][N];
int main()
{
int T,n,c,L,R;
cin>>T;
while(T--)
{
scanf("%d%d%d%d",&n,&c,&L,&R);
L-=c,R-=c;
ll ans= L==0 ;
memset(dp,0,sizeof(dp));
dp[0][0]=1;
int now=1;
for(int i=1;i*(i+1)/2<=R;i++)
{
for(int j=i*(i+1)/2;j<=R;j++)
{
dp[now][j]=(dp[1-now][j-i]+dp[now][j-i])%mod;
if(L<=j&&j<=R)
ans=(ans+dp[now][j])%mod;
}
now=1-now;
memset(dp[now],0,sizeof(dp[now]));//
}
printf("%lld\n",ans);
}
return 0;
}