Problem Author: | Hasan Saleh (MathModel) |
Prepared by: | Hasan Saleh (MathModel) |
Edited by: | Hasan Saleh (MathModel) |
Solution
Let be a multiset of size , with value-sum S=\sum a_i, and let c_x be the multiplicity of value in .
For a fixed permutation and position (1\le p\le n), the coefficient of the element placed at in the sum of all subarrays equals
Indeed, there are choices for the left end and (n-p+1) for the right end that include .
Summing over positions and then over permutations: - The number of distinct permutations of a multiset is \dfrac{n!}{\prod_x c_x!}. - By symmetry across distinct permutations, the average value at any position is . - Hence the total contribution factor of equals
A standard identity gives
Therefore, for n\ge 1,
and for n=0 the answer is .
So we only need to maintain, after each query: - (current size), - (current sum modulo M=10^9+7), - D=\left(\prod_x c_x!\right)^{-1}\pmod M.
Updates are : - On inserting : let t=c_x before the insert, then c_x\!\leftarrow\! t+1 and
- On removing : let t=c_x before the removal, then c_x\!\leftarrow\! t-1 and
We precompute and modular inverses up to 2\cdot 10^6 (since \sum(n+q)\le 2\cdot 10^6), and also need 6^{-1}\bmod M to get \binom{n+2}{3}=\dfrac{n(n+1)(n+2)}{6}.
Answer at each step (for n>0):
#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();
}