可以优化空间,倒序枚举k即可
我该如何骂我自己好呢?
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define maxn 510 #define mod 1000000007 using namespace std; struct yts { int l,r; }q[maxn],seq[2*maxn]; int a[2*maxn]; int inv[1010]; int f[2*maxn][maxn],len[2*maxn]; int sum[2*maxn]; int dp[maxn][2*maxn]; int n,m,tot,num; int query_l(int x) { int l=1,r=num,ans; while (l<=r) { int mid=(l+r)/2; if (x<=seq[mid].l) ans=mid,r=mid-1; else l=mid+1; } return ans; } int query_r(int x) { int l=1,r=num,ans; while (l<=r) { int mid=(l+r)/2; if (seq[mid].r<x) ans=mid,l=mid+1; else r=mid-1; } return ans; } int power(int x,int y) { int ans=1; while (y) { if (y&1) ans=(long long)ans*x%mod; x=(long long)x*x%mod; y>>=1; } return ans; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); y++; q[i].l=x;q[i].r=y; a[++tot]=x;a[++tot]=y; } for (int i=1;i<=1000;i++) inv[i]=power(i,mod-2); sort(a+1,a+tot+1); for (int i=1;i<tot;i++) if (a[i]!=a[i+1]) seq[++num].l=a[i],seq[num].r=a[i+1]-1,len[num]=a[i+1]-a[i]; for (int i=1;i<=n;i++) q[i].l=query_l(q[i].l),q[i].r=query_r(q[i].r); for (int i=0;i<=num;i++) sum[i]=1; for (int i=1;i<=n;i++) { for (int j=1;j<=num;j++) dp[i][j]=dp[i-1][j]; for (int j=q[i].l;j<=q[i].r;j++) dp[i][j]++; } for (int i=1;i<=n;i++) { for (int j=q[i].l;j<=q[i].r;j++) { for (int k=dp[i][j];k>=2;k--) f[j][k]=(f[j][k]+((long long)f[j][k-1]*(len[j]-k+1)%mod)*inv[k]%mod)%mod; f[j][1]=(f[j][1]+(long long)sum[j-1]*len[j]%mod)%mod; } sum[0]=1; for (int j=1;j<=num;j++) { sum[j]=sum[j-1]; for (int k=1;k<=dp[i][j];k++) sum[j]=(sum[j]+f[j][k])%mod; } } int ans=0; for (int i=1;i<=num;i++) for (int j=1;j<=n;j++) ans=(ans+f[i][j])%mod; printf("%d\n",ans); return 0; }