本文共 865 字,大约阅读时间需要 2 分钟。
操作 ( l , r , k ) (l,r,k) (l,r,k)表示
l ∼ r l\sim r l∼r这段区间,对于每个 i i i,加上 C k i + k − l C_k^{i+k-l} Cki+k−l我们可以发现对于一个全是1的序列,求 k k k次前缀和,就是杨辉三角的第 k + 1 k+1 k+1列,那么对于次修改,我们用k阶差分修改。最后取 k k k次前缀和
#include#include #define N 500050#define ll long longusing namespace std;ll n,m,c[N][25],s[N][25],l,r,k;const ll XJQ=1e9+7;int main(){ scanf("%lld%lld",&n,&m); c[0][0]=1; for(ll i=1;i<=n+20;i++)//预处理C { c[i][0]=1; for(ll j=1;j<=min(i,20ll);j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%XJQ; } for(ll i=1;i<=m;i++) { scanf("%lld%lld%lld",&l,&r,&k); for(ll j=0;j<=k;j++)//k阶差分 { (s[l][j]+=c[k][k-j])%=XJQ; (s[r+1][j]-=c[r-l+k+1][k-j])%XJQ; } } for(ll i=1;i<=n;i++) for(ll j=0;j<=20;j++)//k次前缀合 s[i+1][j]=(((s[i+1][j]+s[i][j]%XJQ+XJQ)+s[i][j+1])%XJQ+XJQ)%XJQ; for(ll i=1;i<=n;i++) printf("%lld\n",s[i][0]);}
转载地址:http://oxzaf.baihongyu.com/