JZOJ5922. 【NOIP2018模擬10.23】sequence
阿新 • • 發佈:2018-11-03
Description
小 F 是一位 Hack 國的居民,他生活在一條長度為 n 的街道上,這個街道上總共有 n 個商店。每個商店裡售賣著不同的 Hack 技能包,每個商店本身也會有個便利值。初始時,每個商店的便利值均為 0。每一天,街道上都會有一些商店優化改造。
具體來說,對於每一天,優化改造的商店都是一個連續的區間 l ∼ r,每次優化改造也會有一個優化引數 k。對於所有 l ≤ i ≤ r ,第 i 個商店的便利值會增加
。
小 F 想知道,m 天之後,每個商店的便利值分別是多少。由於小 F 並不喜歡高精度,因此你只需要輸出便利值對 10^9 + 7 取模的結果。
題解
可以知道,每一個加操作,都是從1開始的,
考慮用差分陣列,但是這裡這裡並不是簡單的差分,而是k階差分。
具體做法跟求C類似一階一階往上算。
code
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string.h> #include <cmath> #include <math.h> #define N 500003 #define P putchar #define G getchar using namespace std; char ch; void read(int &n) { n=0; ch=G(); while((ch<'0' || ch>'9') && ch!='-')ch=G(); int w=1; if(ch=='-')w=-1,ch=G(); while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G(); n*=w; } void write(int x){if(x>9) write(x/10);P(x%10+'0');} const int mo=1000000007; int s[23][N],n,m,l,r,k,c[23][N]; int add(int x,int y){return (x+y<mo?x+y:x+y-mo);} int main() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); read(n);read(m); for(int i=0;i<=n+2;i++)c[0][i]=1; for(int i=1;i<21;i++) for(int j=i;j<=n+2;j++) c[i][j]=add(c[i-1][j-1],c[i][j-1]); for(int i=1;i<=m;i++) { read(l);read(r);read(k); s[k][l]++;s[k][r+1]--; for(int j=k-1;j>=0;j--)s[j][r+1]=add(s[j][r+1],mo-c[k-j][r-l+k-j]); } for(int i=20;i+1;i--) for(int j=1;j<=n;j++) s[i][j]=add(s[i][j],add(s[i][j-1],s[i+1][j])); for(int i=1;i<=n;i++) write(s[0][i]),P('\n'); return 0; }