CodeForces 408E Curious Array(组合数学+差分)
You've got an array consisting of n integers: a[1], a[2], ..., a[n]. Moreover, there are m queries, each query can be described by three integers li, ri, ki. Query li, ri, ki means that we should add to each element a[j], where li ≤ j ≤ ri.
Record means the binomial coefficient, or the number of combinations from yelements into groups of x elements.
You need to fulfil consecutively all queries and then print the final array.
Input
The first line contains integers n, m (1 ≤ n, m ≤ 105).
The second line contains n integers a[1], a[2], ..., a[n] (0 ≤ ai ≤ 109) — the initial array.
Next m lines contain queries in the format li, ri, ki — to all elements of the segment li... ri add number (1 ≤ li ≤ ri ≤ n; 0 ≤ k ≤ 100).
Output
Print n integers: the i-th number is the value of element a[i] after all the queries. As the values can be rather large, print them modulo 1000000007 (109 + 7).
Examples
5 1
0 0 0 0 0
1 5 0
1 1 1 1 1
10 2
1 2 3 4 5 0 0 0 0 0
1 6 1
6 10 2
2 4 6 8 10 7 3 6 10 15
题意:给出n个数,m次操作
每次操作给出li,ri,ki
将li-ri的范围里的第j个数加上
题解:考虑到上面的ki是在每个操作里是不会变的
考虑在杨辉三角中找规律
![](https://images2018.cnblogs.com/blog/1188068/201807/1188068-20180725183059808-1053939674.png)
k=i是k=i-1的前缀和
然后可以考虑差分
在高维进行好差分后一维一维的降下来
注意差分的时候要每一层都差分
代码如下:
#include<map> #include<cmath> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #define mod 1000000007 using namespace std; long long fac[200010],inv[200010],n,m,a[110][100010],sum[110][100010]; long long kasumi(long long a,long long b) { long long ans=1ll; while(b) { if(b&1) { ans=ans*a%mod; } a=a*a%mod; b>>=1; } return ans; } long long c(long long a,long long b) { return fac[a]*inv[b]%mod*inv[a-b]%mod; } int main() { fac[0]=1,inv[0]=1; for(int i=1; i<=200000; i++) { fac[i]=fac[i-1]*i*1ll%mod; } inv[200000]=kasumi(fac[200000],mod-2); for(int i=199999; i>=1; i--) { inv[i]=inv[i+1]*(i+1)*1ll%mod; } scanf("%lld%lld",&n,&m); for(int i=0; i<n; i++) { scanf("%lld",&a[0][i]); } long long l,r,k; while(m--) { scanf("%lld%lld%lld",&l,&r,&k); l--,k++; a[k][l]++; for(int i=1; i<=k; i++) { a[i][r]-=c(k-i+r-l-1,k-i); a[i][r]=(a[i][r]+mod)%mod; } } for(int k=108; k>=0; k--) { for(int i=0;i<n;i++) { a[k][i]+=sum[k+1][i+1]; a[k][i]%=mod; } for(int i=0;i<n;i++) { sum[k][i+1]+=sum[k][i]+a[k][i]; sum[k][i+1]%=mod; } } for(int i=0;i<n;i++) { printf("%lld ",a[0][i]%mod); } }