bzoj 4597 隨機序列

來源:互聯網
上載者:User

標籤:

Description你的面前有N個數排成一行。分別為A1, A2, … , An。你打算在每相鄰的兩個 Ai和 Ai+1 間都插入一個加號或者減號或者乘號。那麼一共有 3^(n-1) 種可能的運算式。你對所有可能的運算式的值的和非常感興趣。但這畢竟太簡單了,所以你還打算支援一個修改操作,可以修改某個Ai 的值。你能夠編寫一個程式對每個修改都輸出修改完之後所有可能運算式的和嗎?注意,修改是永久的,也就是說每次修改都是在上一次修改的基礎上進行, 而不是在最初的運算式上進行。

 

Input第一行包含 2 個正整數 N 和 Q,為數的個數和詢問的個數。接下來一行 n 個非負整數,依次表示a1,a2...an在接下來 Q 行,其中第 ?? 行兩個非負整數Ti 和Vi,表示要將 Ati 修改為 Vi。其中 1 ≤ Ti ≤ N。保證對於 1 ≤ J ≤ N, 1 ≤ i≤ Q,都有 Aj,Vi ≤ 10^4。N,Q<=100000,本題僅有三組資料

 

Output輸出共 Q 行,其中第 i 行表示第 i 個詢問之後所有可能運算式的和,對10^9 + 7 模數。 題解首先想到+、-號會導致後面的所有結果相互抵消。所以對答案有貢獻的是前面一直是連乘的部分。即第一個非乘號的前面部分所以我們只需要維護首碼積,修改的時候線段樹區間修改,先預先處理逆元就可以做了我認為這道題最關鍵的地方就是+、-號相互抵消,一下子簡化了問題。一開始想是否有規律,真實太蠢了 
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define maxn 100020 7  8 typedef long long ll; 9 const ll mod = 1e9 + 7;10 struct node{11     int ls,rs;12     ll sum,mul;13 }sgt[maxn * 4];14 ll inv[maxn],fac[maxn],sum[maxn],pow[maxn];15 int n,a[maxn],q,rt,tot;16 17 inline ll power(ll x,int y){18     ll res = 1;19     while ( y ){20         if ( y & 1 ) res = res * x % mod;21         x = x * x % mod;22         y >>= 1;23     }24     return res % mod;25 }26 void init(){27     for (int i = 1 ; i <= 10000 ; i++) inv[i] = power(i,mod - 2);28     pow[0] = 1;29     for (int i = 1 ; i <= 100000 ; i++) pow[i] = pow[i - 1] * 3ll % mod;30 }31 inline void update(int x){32     sgt[x].sum = sgt[sgt[x].ls].sum + sgt[sgt[x].rs].sum;33     if ( sgt[x].sum >= mod ) sgt[x].sum -= mod;34 }35 void build(int &x,int l,int r){36     x = ++tot;37     sgt[x].mul = 1;38     if ( l == r ){39         if ( l == n ) sgt[x].sum = sum[l];40         else sgt[x].sum = sum[l] * pow[n - l - 1] * 2ll % mod;41         return;42     }43     int mid = (l + r) >> 1;44     build(sgt[x].ls,l,mid);45     build(sgt[x].rs,mid + 1,r);46     update(x);47 }48 inline void mul(int x,ll d){49     sgt[x].sum = sgt[x].sum * (ll)d % mod;50     sgt[x].mul = sgt[x].mul * (ll)d % mod; 51 }52 inline void pushdown(int x){53     if ( sgt[x].mul != 1 ){54         mul(sgt[x].ls,sgt[x].mul);55         mul(sgt[x].rs,sgt[x].mul);56         sgt[x].mul = 1;57     }58 }59 void modify(int x,int l,int r,int ls,int rs,ll d){60     if ( ls <= l && rs >= r ){61         mul(x,d);62         return;63     }64     pushdown(x);65     int mid = (l + r) >> 1;66     if ( ls <= mid ) modify(sgt[x].ls,l,mid,ls,rs,d);67     if ( rs > mid ) modify(sgt[x].rs,mid + 1,r,ls,rs,d);68     update(x);69 }70 int main(){71     //freopen("input.txt","r",stdin);72     scanf("%d %d",&n,&q);73     init();74     for (int i = 1 ; i <= n ; i++){75         scanf("%d",&a[i]);76     }77     sum[0] = 1;78     for (int i = 1 ; i <= n ; i++) sum[i] = a[i] * sum[i - 1] % mod;79     build(rt,1,n);80     while ( q-- ){81         int id,v;82         scanf("%d %d",&id,&v);83         modify(rt,1,n,id,n,inv[a[id]]);84         modify(rt,1,n,id,n,v);85         a[id] = v;86         printf("%lld\n",sgt[rt].sum);87     }88     return 0;89 }

 

bzoj 4597 隨機序列

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.