件名の説明:
\(1 <= N、AI <= 5 * 10 ^ 5 \)
ソリューション:
私は精神的に私は、直線性を期待していません。
集合\(Eは、([I] )\) を減算することが望まi番目の数を表します。
\(Eは、([1])= [1] \)
見つけるのは難しいことではありません\(E([I] )は、(i> 1)\) 互いに独立の間、実際には、それは難しいです。
2が固定考慮して、彼らは確率のように2つのオプションがあり、うまく上の他を無視することを選択しました。
のみ考える\(N = 2 \)場合、直接暴力列挙\([1] \)端で\([I] \)が存在することにより、いくつかの2 \オーバー\(1 \ )いくつかの当事者との組み合わせの数は、次式:
\(= [I] - \ sum_ {I} = 0 {I ^ [I] -1 C_ {A} ^ {-1} + [1] [I] -1} * { 1 \ over2} ^ {[1] + I} *([I] -i)\)
この方法は、順次再帰得るために使用することができる\([I] = 1,2,3 ... \) の回答を。
時間の複雑さ:\(O(N + MAX(A))\)
コード:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int mo = 323232323;
ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
}
const ll ni2 = ksm(2, mo - 2);
const int N = 1e6 + 5;
int n, a[N];
ll fac[N], nf[N], a2[N];
void build(int n) {
fac[0] = 1; fo(i, 1, n) fac[i] = fac[i - 1] * i % mo;
nf[n] = ksm(fac[n], mo - 2); fd(i, n, 1) nf[i - 1] = nf[i] * i % mo;
a2[0] = 1; fo(i, 1, n) a2[i] = a2[i - 1] * ni2 % mo;
}
ll C(int n, int m) {
return fac[n] * nf[m] % mo * nf[n - m] % mo;
}
ll f[N], g[N];
int main() {
freopen("b.in", "r", stdin);
freopen("b.out", "w", stdout);
scanf("%d", &n);
fo(i, 1, n) scanf("%d", &a[i]);
build(1e6 + 2);
fo(i, 0, 5e5) {
if(i) f[i] = f[i - 1], g[i] = g[i - 1];
f[i] = (f[i] + a2[a[1] + i] * C(a[1] + i - 1, i)) % mo;
g[i] = (g[i] + a2[a[1] + i] * C(a[1] + i - 1, i) % mo * i) % mo;
}
ll ans = a[1];
fo(i, 2, n) {
ans += a[i];
ans -= (f[a[i] - 1] * a[i] - g[a[i] - 1]) % mo;
}
ans = (ans % mo + mo) % mo;
pp("%lld\n", ans);
}