結果
| 問題 |
No.535 自然数の収納方法
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-03-31 21:49:00 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 709 ms / 2,000 ms |
| コード長 | 2,145 bytes |
| コンパイル時間 | 2,107 ms |
| コンパイル使用メモリ | 199,648 KB |
| 実行使用メモリ | 504,912 KB |
| 最終ジャッジ日時 | 2025-03-31 21:49:11 |
| 合計ジャッジ時間 | 9,974 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 23 |
ソースコード
#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
namespace IO{
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void write(ll x){
if(x<0){
putchar('-');
x=-x;
}
if(x>=10)write(x/10);
putchar(x%10+'0');
return;
}
}
using namespace IO;
int n;ll ans;
const ll mod=1e9+7;
int cnt,head[50000010],tot;
inline int newnode(){return ++tot;}
struct EDGE{int v,nxt;}edge[14000010];
inline void addedge(int u,int v){edge[++cnt]={v,head[u]};head[u]=cnt;return;}
ll f[50000010];
int DGR[50000010],dgr[50000010];
inline void link(int v,int u){
addedge(u,v);DGR[v]++;
return;
}
int id[2005][2005],suf[2005][2005];
inline void dp(){
for(int i=0;i<=tot;++i)f[i]=0,dgr[i]=DGR[i];
queue<int>q;
for(int i=1;i<=tot;++i)if(dgr[i]==0)q.push(i),f[i]=1;
while(q.size()){
int now=q.front();q.pop();
for(int i=head[now];i;i=edge[i].nxt){
int v=edge[i].v;
f[v]=(f[v]+f[now])%mod;
dgr[v]--;
if(dgr[v]==0)q.push(v);
}
}
return;
}
inline void Dp(){
for(int i=0;i<=tot;++i)f[i]=0,dgr[i]=DGR[i];
queue<int>q;
for(int i=1;i<=tot;++i)if(dgr[i]==0)q.push(i),f[i]=1;
f[id[n-1][n]]=0;
while(q.size()){
int now=q.front();q.pop();
for(int i=head[now];i;i=edge[i].nxt){
int v=edge[i].v;
f[v]=(f[v]+f[now])%mod;
dgr[v]--;
if(dgr[v]==0)q.push(v);
}
}
return;
}
signed main(){
// freopen("number.in","r",stdin);
// freopen("number.out","w",stdout);
n=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)id[i][j]=newnode();
for(int i=2;i<n-1;++i){
for(int j=n;j>=1;--j){
suf[i][j]=newnode();
if(j!=n)link(suf[i][j],suf[i][j+1]);
link(suf[i][j],id[i+1][j]);
}
}
for(int i=2;i<n-1;++i)
for(int j=1;j<=n;++j){
int res=max(1ll,j-i+1);
link(id[i][j],suf[i][res]);
}
ll ressum=0;dp();
for(int i=n;i>=1;--i){
ressum=(ressum+1ll*f[id[2][i]])%mod;
ans=(ans+1ll*ressum*(i-1))%mod;
}
ressum=0;Dp();
for(int i=n;i>=1;--i)ressum=(ressum+1ll*f[id[2][i]])%mod,ans=(ans+ressum)%mod;
write(ans);
return 0;
}