Altmassivlərin Permutasiyaları və Sorğular#12256

Altmassivlərin Permutasiyaları və Sorğular (Həll təhlili)

Problemin Müəllifi:

Hasan Saleh (MathModel)

Hazırlayan:

Hasan Saleh (MathModel)

Redaktə edən:

Hasan Saleh (MathModel)

Həll

-nı ölçüsü olan bir çoxluq, dəyər cəmi S=\sum a_i və c_x-i -da dəyər -in çoxluğunu göstərən bir çoxluq olaraq qəbul edək.

Müəyyən bir permutasiya və mövqe (1\le p\le n) üçün, -də yerləşdirilən elementin bütün altmassivlərin cəmi içindəki koeffisiyenti bərabərdir

w_p \;=\; p\,(n-p+1).

Həqiqətən, üçün sol ucu seçmək üçün seçim var və -ni daxil edən sağ ucu seçmək üçün (n-p+1) seçim var.

Mövqe üzrə cəmləmə və sonra permutasiyalar üzrə cəmləmə: - Bir çoxluğun fərqli permutasiyalarının sayı \dfrac{n!}{\prod_x c_x!}-dir. - Fərqli permutasiyalar arasında simmetriya ilə, hər mövqedə orta dəyər -dir. - Beləliklə, -nin ümumi töhfə faktoru bərabərdir

\frac{n!}{\prod_x c_x!}\cdot \frac{1}{n}\cdot \sum_{p=1}^n w_p \;=\; \frac{n!}{\prod_x c_x!}\cdot \frac{1}{n}\cdot \sum_{p=1}^n p(n-p+1).

Standart bir identiklik verir

\sum_{p=1}^n p(n-p+1) \;=\; \binom{n+2}{3}.

Buna görə, n\ge 1 üçün,

\boxed{\;\text{Cavab} = \frac{n!}{\prod_x c_x!}\cdot \frac{1}{n}\cdot \binom{n+2}{3}\cdot S = (n-1)!\cdot \binom{n+2}{3}\cdot \frac{S}{\prod_x c_x!}\;}

və n=0 üçün cavab -dır.

Beləliklə, hər sorğudan sonra yalnız aşağıdakılara nəzarət etməliyik: - (hazırkı ölçü), - (hazırkı cəm modulu M=10^9+7), - D=\left(\prod_x c_x!\right)^{-1}\pmod M.

Yeniləmələr -dir: - əlavə edərkən: t=c_x əlavə etmədən əvvəl, c_x\!\leftarrow\! t+1 və

D \leftarrow D\cdot (t+1)^{-1}\pmod M .

- silərkən: t=c_x silməzdən əvvəl, c_x\!\leftarrow\! t-1 və

D \leftarrow D\cdot t\pmod M .

Biz və modul tərsini 2\cdot 10^6-a qədər əvvəlcədən hesablayırıq (çünki \sum(n+q)\le 2\cdot 10^6), həmçinin \binom{n+2}{3}=\dfrac{n(n+1)(n+2)}{6}-nı əldə etmək üçün 6^{-1}\bmod M-ə ehtiyacımız var.

Hər addımda cavab (üçün n>0):

\text{Cavab} \equiv (n-1)!\ \cdot\ \binom{n+2}{3}\ \cdot\ S\ \cdot\ D \pmod M.
#include <bits/stdc++.h>

using namespace std;
using ll=long long;
const int M=1e9+7;
#pragma GCC optimize("O3")
#pragma GCC optimization("Ofast,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

int f[2000005],inv[2000005];

int fpow(int a,ll e){
    ll r=1;
    while(e){
        if(e&1)r=r*a%M;
        a=1LL*a*a%M;
        e>>=1;
    }
    return (int)r;
}

int mul(int a,int b){ return (int)(1LL*a*b%M); }

int W(int n,int w6){ 
    return mul(mul((int)(1LL*n*(n+1)%M),(n+2)%M),w6);
}

int calc(int n,int den,ll S,int w6){
    if(!n) return 0;
    return mul(mul(f[n-1],den),mul(W(n,w6),(S%M+M)%M));
}

void solve(){
    int n,q; cin>>n>>q;
    f[0]=1;
    for(int i=1;i<=2000000;i++)f[i]=mul(f[i-1],i);
    inv[2000000]=fpow(f[2000000],M-2);
    for(int i=2000000;i;i--)inv[i-1]=mul(inv[i],i);
    int w6=fpow(6,M-2);

    unordered_map<ll,int> mp;
    ll S=0;
    int den=1;

    for(int i=0;i<n;i++){
        ll x; cin>>x;
        S+=x;
        int t=mp[x]++;                 
        den=mul(den, mul(f[t],inv[t+1]));
    }

    cout<<calc(n,den,S,w6)<<' ';
    while(q--){
        char c; ll x; cin>>c>>x;
        if(c=='+'){
            S+=x;
            int t=mp[x]++;
            den=mul(den, mul(f[t],inv[t+1])); 
            n++;
        }else{
            S-=x;
            int t=mp[x]--;                    
            den=mul(den, t);                 
            if(mp[x]==0) mp.erase(x);
            n--;
        }
        cout<<calc(n,den,S,w6)<<' ';
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T=1;
    while(T--)solve();
}