codeforces 407C Curious Array

來源:互聯網
上載者:User

標籤:class   math   差分   i+1   ade   開始   bit   uri   inline   

目錄

  • codeforces 407C Curious Array
  • 題意:
  • 題解:
  • Code:
codeforces 407C Curious Array

題目傳送們

題意:

給出一個長度為\(n\)序列,每次給出三個值\(l\),\(r\),\(k\),表示給區間\([l,r]\)中的每一個數\(a_j(l \leq j \leq r)\)加上\(\tbinom{j-l+k}{k}\),求\(m\)次操作之後每個位置上的值對\(10^9+7\)模數的結果。
\((1 \leq n,m \leq 10^5 , 1 \leq a_i \leq 10^9 , 1 \leq l_i,r_i \leq n,0 \leq k \leq 100 )\)

題解:

考慮到題目中的\(k\)比較的小,所以我們大致往這個方向入手。我們先從簡單的開始考慮,如果\(k=0\),則相當於在\([l,r]\)區間中每個數都加上1,只需要差分一下,然後修改完之後首碼和一下即可。然後我們繼續考慮\(k=1\)的情況,那麼我們就是在第一個位置上加1,第二個位置上加2...然後每個位置加的數字都相差1。於是我們很容易就想到將加的操作首碼差分一下,那麼轉化成了\(k=0\)的情況。根據這個,我們就可以大膽的推斷出\(k=x\)的情況下首碼差分一下就可以轉化成\(k=x-1\)的情況。經過檢驗發現確實是這樣的。實際上這是因為組合數的公式\(\tbinom{n}{m}=\tbinom{n-1}{m-1}+\tbinom{n-1}{m}\),這個滿足首碼差分的性質,所以可以把這個操作轉化成\(k\)階差分。
然後我們會發現一個情況,以給長度為四的區間加上2的貢獻時,如果我們只在一層首碼和之中差分,會出現這樣的情況:
先進行差分:0 1 0 0 0 -1 \(\to\) 進行首碼和一次:0 1 1 1 1 0 (到這裡都是對的) \(\to\) 再次進行首碼和: 0 1 2 3 4 5 \(\to\) 0 1 3 6 10 15
我們會發現,雖然中間長度為4的區間確實加上了2的貢獻,但是最後的一個區間卻多加了貢獻。所以我們僅在第一層中進行差分是不夠的,還需要在之後的幾層中進行差分,並且每一層差分減去的組合數剛好是\(C[\)層數\(-1+k][k]\),這樣我們再次進行首碼和之後就可以消除多餘的貢獻了。總共的複雜度為\(O(nk)\)。

Code:
#pragma GCC optimize (2,"inline","Ofast")#include <bits/stdc++.h>using namespace std;typedef long long ll;bool Finish_read;template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}/*================Header Template==============*/#define PAUSE printf("Press Enter key to continue..."); fgetc(stdin);const int N=1e5+500;const int Md=1e9+7;const int K=103;int n,m;struct mo {    int l,r,k;}q[N];int C[N][K],tmp[N][K],res[N][K],a[N];/*==================Define Area================*/int Add(const int &x,const int &y) {return (x+y)>=Md?(x+y-Md):(x+y);}int Sub(const int &x,const int &y) {return (x-y<0)?(x-y+Md):(x-y);}void Init() {    C[0][0]=1;    for(int i=1;i<N-450;i++) {        C[i][0]=1;        for(int j=1;j<=min(i,K-1);j++) {            C[i][j]=Add(C[i-1][j-1],C[i-1][j]);        }    }}int main() {    read(n);read(m);    for(int i=1;i<=n;i++) read(a[i]);    Init();    for(int i=1,l,r,k;i<=m;i++) {        read(l);read(r);read(k);        tmp[l][k+1]++;        for(int j=k+1;j;j--) {            tmp[r+1][j]=Sub(tmp[r+1][j],C[k-j+1+r-l][k-j+1]);        }           }    for(int i=101;~i;i--) {        for(int j=1;j<=n;j++) res[j][i]=Add(res[j][i],res[j][i+1]);        for(int j=1;j<=n;j++) res[j][i]=Add(res[j][i],res[j-1][i]);        for(int j=1;j<=n;j++) res[j][i]=Add(res[j][i],tmp[j][i]);    }    for(int i=1;i<=n;i++) {        printf("%d ",Add(res[i][0],a[i]));    }    puts("");    return 0;}

codeforces 407C Curious Array

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.