Argon_Cube
2025-01-10 15:00:49
不会简单容斥/ll
显然有一个暴力的
两个区间
如果只需要管一个条件多好啊!这样就只需要记录其中一个端点(条件 1. 需要记录右端点,2. 需要记录左端点)的位置,状态就只有二维了。
于是我们考虑对于每个
容易发现如果某个方案不合法,那么在不合法的位置一定恰好满足了一个条件,所以就可以将它的贡献一正一负抵消;合法的方案无论怎么选取条件都是合法的所以会被算恰好
于是设
可以发现
#include <algorithm>
#include <iostream>
#include <vector>
#include <bitset>
#include <string>
#include <array>
#define rgall(arr) (arr).begin(),(arr).end()
#define rgcnt(arr,cnt) (arr).begin(),(arr).begin()+(cnt)
#define rgo1(arr,cnt) (arr).begin()+1,(arr).begin()+1+(cnt)
#define rgany(arr,cnt,offset) (arr).begin()+(offset),(arr).begin()+(offset)+(cnt)
using namespace std;
long long fast_pow(long long base,long long exp,long long moder)
{
long long result;
for(result=1;exp;exp&1?result=result*base%moder:true,base=base*base%moder,exp>>=1);
return result;
}
vector<long long> dp,dp0;
int main(int argc,char* argv[],char* envp[])
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long n,m,moder;
cin>>n>>m>>moder;
dp.resize(m+4),dp[m]=1;
for(int i=1;i<=n;i++)
{
dp0=dp,fill(rgall(dp),0);
for(int j=1;j<=m;j++)
{
long long a=dp0[m-j+1];
dp[j]+=a*j%moder,dp[j+1]-=a*(j-1)%moder,dp[m-j+2]-=a;
}
for(int j=1;j<=m;j++)
(dp[j]+=dp[j-1])%=moder;
for(int j=1;j<=m;j++)
(dp[j]+=dp[j-1]+moder*2)%=moder;
}
long long answer=0;
for(int j=1;j<=m;j++)
answer+=dp[j];
cout<<answer%moder;
return 0;
}