题目
有n个操作,l,r,k,每次操作对于
i
∈
[
l
,
r
]
i∈[l,r]
i∈[l,r]给
a
[
i
]
+
=
C
i
−
l
+
k
k
a[i]+=C_{i-l+k}^k
a[i]+=Ci−l+kk
求
a
[
]
a[]
a[]。
n
≤
1
e
5
,
k
≤
20
n\leq 1e5,k\leq 20
n≤1e5,k≤20
题解
k阶前缀和
一个数组,只有第一个元素是1,其余都是0.
进行一次前缀和后,每个元素都是1
进行2次前缀和后,第i个元素为
C
(
1
,
i
)
C(1,i)
C(1,i)
进行3次前缀和后,第i个元素为
C
(
2
,
i
+
1
)
C(2,i+1)
C(2,i+1)
……
进行k次前缀和后,第i个元素为
C
(
k
,
i
+
k
−
1
)
C(k,i+k-1)
C(k,i+k−1)
研究k=1的数据点,考虑用前缀和解决此问题。
考虑对一个二维数组进行前缀和。
k次前缀和,且k不是很大,用k行存储一下。
每个操作对答案的贡献显然是互不影响的。
对于操作l,r,k
f
[
l
]
[
k
]
+
=
1
f[l][k]+=1
f[l][k]+=1
f
[
r
+
1
]
[
j
]
−
=
C
(
r
−
l
+
(
k
−
j
)
,
k
−
j
)
f[r+1][j]-=C(r-l+(k-j),k-j)
f[r+1][j]−=C(r−l+(k−j),k−j)
最后
f
[
i
]
[
0
]
f[i][0]
f[i][0]即为答案。
其他解法
每个操作
l
,
r
,
k
l,r,k
l,r,k,
i
∈
[
l
,
r
]
i∈[l,r]
i∈[l,r],
a
[
i
]
+
=
(
i
−
l
+
1
)
∗
(
i
−
l
+
2
)
∗
.
.
.
∗
(
i
−
l
+
k
)
k
!
a[i]+=\frac{(i-l+1)*(i-l+2)*...*(i-l+k)}{k!}
a[i]+=k!(i−l+1)∗(i−l+2)∗...∗(i−l+k)
将i看成是未知数,那么这个多项式的次数最多是20.
可以将每一项的系数求出来,然后打2个tag就好了。
时间复杂度
O
(
n
k
2
)
O(nk^2)
O(nk2)
#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 500010
#define K 21
#define mo 1000000007
#define P(a) putchar(a)
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
int jc[N],ny[N];
int f[N][K],a[K],b[K];
int i,j,u,k,l,r,n,m,ans,w,K1;
int read(){
int rs=0,fh=0;char ch=0;
while(ch<'0'||ch>'9')fh|=ch=='-',ch=getchar();
while(ch>='0'&&ch<='9')rs=(rs<<3)+(rs<<1)+(ch^'0'),ch=getchar();
return fh?-rs:rs;
}
void write(int x){
if(x>9)write(x/10);
P(x%10+'0');
}
int ksm(int x,int y){
int rs=1;
for(;y;y>>=1,x=(1ll*x*x)%mo)if(y&1)rs=(1ll*rs*x)%mo;
return rs;
}
int main(){
jc[0]=jc[1]=ny[0]=ny[1]=1;
fo(i,2,20)jc[i]=(1ll*jc[i-1]*i)%mo;
fo(i,2,20)ny[i]=ksm(jc[i],mo-2);
n=read();m=read();
fo(i,1,m){
l=read(),r=read(),k=read();
if(k==0){
f[l][0]=(f[l][0]+1)%mo;
f[r+1][0]=(f[r+1][0]-1+mo)%mo;
continue;
}
K1=K1>k?K1:k;
a[0]=(1-l+mo)%mo;
a[1]=1;
fo(j,2,k){
w=(mo+j-l)%mo;
a[j]=0;
fo(u,0,j)b[u]=a[u];
fo(u,1,j)a[u]=b[u-1];
a[0]=0;
fo(u,0,j-1)a[u]=(a[u]+1ll*b[u]*w)%mo;
}
fo(j,0,k){
w=1ll*a[j]*ny[k]%mo;
f[l][j]=(f[l][j]+w)%mo;
f[r+1][j]=(f[r+1][j]-w+mo)%mo;
}
}
fo(i,0,K1)a[i]=0;
fo(i,1,n){
fo(j,0,K1)a[j]=(a[j]+f[i][j])%mo;
w=1;ans=0;
fo(j,0,K1){
ans=(ans+1ll*a[j]*w%mo)%mo;
w=(1ll*w*i)%mo;
}
write(ans),P('\n');
}
return 0;
}