結果
問題 |
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; }