E99 线性DP+前缀和优化 P3643 [APIO2016] 划艇
视频链接:E99 线性DP+前缀和优化 P3643 [APIO2016] 划艇_哔哩哔哩_bilibili
参考:G13 同余式 乘法逆元 费马小定理 - 董晓 - 博客园
// 线性DP+前缀和优化 O(n^3) #include<bits/stdc++.h> using namespace std; #define int long long const int N=505,M=1e9+7; int n,m,ans; int a[N],b[N],x[N<<1],inv[N],C[N],f[N],g[N]; int qpow(int a,int b){ int s=1; while(b){ if(b&1) s=s*a%M; a=a*a%M; b>>=1; } return s; } signed main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i],&b[i]); x[i]=a[i]; //左闭 x[i+n]=++b[i]; //右开 } sort(x+1,x+1+2*n); m=unique(x+1,x+1+2*n)-x-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(x+1,x+1+m,a[i])-x; b[i]=lower_bound(x+1,x+1+m,b[i])-x; } f[0]=g[0]=C[0]=inv[1]=1; for(int i=2;i<=n;i++) inv[i]=qpow(i,M-2); for(int j=1;j<m;j++){ //第j区间 int L=x[j+1]-x[j]; for(int i=1;i<=n;i++) C[i]=C[i-1]*(L+i-1)%M*inv[i]%M; for(int i=n;i;i--){ //前i学校 if(a[i]<=j&&b[i]>=j+1){ for(int s=1,k=i-1;k>=0;k--){ f[i]=(f[i]+g[k]*C[s])%M; if(a[k]<=j&&b[k]>=j+1) s++; } } g[i]=f[i]; //前缀和 } } for(int i=1;i<=n;i++) ans=(ans+f[i])%M; printf("%d\n",ans); }
// 线性DP+前缀和优化 O(n^3) #include<bits/stdc++.h> using namespace std; #define int long long const int N=505,M=1e9+7; int n,m,ans; int a[N],b[N],x[N<<1],inv[N],C[N],f[N]; int qpow(int a,int b){ int s=1; while(b){ if(b&1) s=s*a%M; a=a*a%M; b>>=1; } return s; } signed main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i],&b[i]); x[i]=a[i]; //左闭 x[i+n]=++b[i]; //右开 } sort(x+1,x+1+2*n); m=unique(x+1,x+1+2*n)-x-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(x+1,x+1+m,a[i])-x; b[i]=lower_bound(x+1,x+1+m,b[i])-x; } f[0]=C[0]=inv[1]=1; for(int i=2;i<=n;i++) inv[i]=qpow(i,M-2); for(int j=1;j<m;j++){ //第j区间 int L=x[j+1]-x[j]; for(int i=1;i<=n;i++) C[i]=C[i-1]*(L+i-1)%M*inv[i]%M; for(int i=n;i;i--){ //前i学校 if(a[i]<=j&&b[i]>=j+1){ for(int s=1,k=i-1;k>=0;k--){ f[i]=(f[i]+f[k]*C[s])%M; if(a[k]<=j&&b[k]>=j+1) s++; } } } } for(int i=1;i<=n;i++) ans=(ans+f[i])%M; printf("%d\n",ans); }
// 线性DP+前缀和优化 O(n^3) #include<bits/stdc++.h> using namespace std; #define int long long const int N=505,M=1e9+7; int n,m,ans; int a[N],b[N],x[N<<1],inv[N],C[N],f[N]; signed main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i],&b[i]); x[i]=a[i]; //左闭 x[i+n]=++b[i]; //右开 } sort(x+1,x+1+2*n); m=unique(x+1,x+1+2*n)-x-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(x+1,x+1+m,a[i])-x; b[i]=lower_bound(x+1,x+1+m,b[i])-x; } f[0]=C[0]=inv[1]=1; for(int i=2;i<=n;i++) inv[i]=(M-M/i)*inv[M%i]%M; for(int j=1;j<m;j++){ //第j区间 int L=x[j+1]-x[j]; for(int i=1;i<=n;i++) C[i]=C[i-1]*(L+i-1)%M*inv[i]%M; for(int i=n;i;i--){ //前i学校 if(a[i]<=j&&b[i]>=j+1){ for(int s=1,k=i-1;k>=0;k--){ f[i]=(f[i]+f[k]*C[s])%M; if(a[k]<=j&&b[k]>=j+1) s++; } } } } for(int i=1;i<=n;i++) ans=(ans+f[i])%M; printf("%d\n",ans); }
// 线性DP+前缀和优化 O(n^3) 滚动数组&正序枚举 #include<bits/stdc++.h> using namespace std; #define int long long const int N=505,M=1e9+7; int n,m,ans; int a[N],b[N],x[N<<1],inv[N],C[N],f[N],g[2][N]; int qpow(int a,int b){ int s=1; while(b){ if(b&1) s=s*a%M; a=a*a%M; b>>=1; } return s; } signed main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i],&b[i]); x[i]=a[i]; //左闭 x[i+n]=++b[i]; //右开 } sort(x+1,x+1+2*n); m=unique(x+1,x+1+2*n)-x-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(x+1,x+1+m,a[i])-x; b[i]=lower_bound(x+1,x+1+m,b[i])-x; } f[0]=g[0][0]=g[1][0]=C[0]=inv[1]=1; for(int i=2;i<=n;i++) inv[i]=qpow(i,M-2); for(int j=1;j<m;j++){ //第j区间 int L=x[j+1]-x[j]; for(int i=1;i<=n;i++) C[i]=C[i-1]*(L+i-1)%M*inv[i]%M; int s=0,t; for(int i=1;i<=n;i++){ //前i学校 if(a[i]<=j&&b[i]>=j+1){ t=++s; for(int k=0;k<=i-1;k++){ if(a[k]<=j&&b[k]>=j+1) t--; f[i]=(f[i]+g[j&1][k]*C[t])%M; } } g[j+1&1][i]=f[i]; //前缀和 } } for(int i=1;i<=n;i++) ans=(ans+f[i])%M; printf("%d\n",ans); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!