PKUSC2018 maximum prefix and

Maximum prefix and

C is a small algorithm contest enthusiast, small C one day met a very difficult problem: find a sequence of sub-sections and maximum.

But small C does not do this problem, the little C decides to randomly disrupt the sequence, and then take the maximum prefix sequence and as the answer.

Small C is a very self-knowledge, he knows his arithmetic completely wrong, so do not care about accuracy, he only cares about the expected value obtained solution, now you help him solve this problem, because the answer may be quite complicated, so you only need to answer output multiplied by \ (n! \) after (998 244 353 \) \ value modulo, obviously this is an integer.

Note: maximum prefix and definitions: \ (\ FORALL I \ in [. 1, n-] \) , \ (\ sum_ {J} = {I}. 1 a_j ^ \) maximum.

For \ (100 \% \) data satisfies \ (. 1 \ Leq n-\ Leq 20 is \) , \ (\ sum_ {I =. 1} ^ {n-} | A [I] | \ Leq 10 ^. 9 \) .

answer

https://www.cnblogs.com/zjp-shadow/p/9141971.html

Not difficult to find, the largest prefix and location \ (p \) all prefixes are not behind \ (> 0 \) . If \ (> 0 \) then there must be a little behind can replace the current answer.

With this idea, then we can consider each sequence is split into two sections, and the split point is the location \ (the p-\) . Note \ (sum_s \) of \ (S \) This state is the algebraic sum of all points.

  1. Note \ (f (s) \) represents \ (S \) maximum prefix set equal to the arrangement and \ (sum_s \) and other less strict prefix and the number of programs. Other prefixes specified here and less in order to avoid re-count.

    So what if \ (sum_s> 0 \) , we can put it behind a single point.

    \[ f(\{u\})\times f(s) \rightarrow f(\{u\}\cup s) \]

  2. Note \ (g (s) \) represents \ (S \) all prefixes are set and arranged \ (\ leq 0 \) is the number of programs.

    If \ (sum_ {S \ Cup \ {U \}} \ Leq 0 \) , then we can \ (S \) into \ (U \) above.

    \[ g(s)\times g(\{u\}) \rightarrow g(s\cup \{u\}) \]

  3. Answer

    \[ ans=\sum_s sum_s\times f(s)\times g([n]\setminus s) \]

Time complexity \ (O (2 ^ NN) \) .

CO int N=131072;
int omg[2][N],rev[N];

void NTT(poly&a,int dir){
    int lim=a.size(),len=log2(lim);
    for(int i=0;i<lim;++i) rev[i]=rev[i>>1]>>1|(i&1)<<(len-1);
    for(int i=0;i<lim;++i)if(i<rev[i]) swap(a[i],a[rev[i]]);
    for(int i=1;i<lim;i<<=1)
        for(int j=0;j<lim;j+=i<<1)for(int k=0;k<i;++k){
            int t=mul(omg[dir][N/(i<<1)*k],a[j+i+k]);
            a[j+i+k]=add(a[j+k],mod-t),a[j+k]=add(a[j+k],t);
        }
    if(dir==1){
        int ilim=fpow(lim,mod-2);
        for(int i=0;i<lim;++i) a[i]=mul(a[i],ilim);
    }
}
poly operator*(poly a,poly b){
    int n=a.size()-1,m=b.size()-1;
    int lim=1<<(int)ceil(log2(n+m+1));
    a.resize(lim),NTT(a,0);
    b.resize(lim),NTT(b,0);
    for(int i=0;i<lim;++i) a[i]=mul(a[i],b[i]);
    NTT(a,1),a.resize(n+m+1);
    return a;
}

vector<int> a[2*N];
int tot,h[2*N],top;

IN bool cmp(int i,int j){
    return a[i].size()>a[j].size();
}
int main(){
    omg[0][0]=1,omg[0][1]=fpow(3,(mod-1)/N);
    omg[1][0]=1,omg[1][1]=fpow(omg[0][1],mod-2);
    for(int i=2;i<N;++i){
        omg[0][i]=mul(omg[0][i-1],omg[0][1]);
        omg[1][i]=mul(omg[1][i-1],omg[1][1]);
    }
    int n=read<int>(),w=read<int>();
    for(int i=2;i<=n;++i){
        int w=read<int>();
        a[++tot].resize(w+1);
        a[tot][0]=1,a[tot][w]=mod-1;
        h[++top]=tot;
    }
    make_heap(h+1,h+top+1,cmp);
    while(top>=2){
        int x=h[1];pop_heap(h+1,h+top+1,cmp),--top;
        int y=h[1];pop_heap(h+1,h+top+1,cmp),--top;
        a[++tot]=a[x]*a[y];
        h[++top]=tot,push_heap(h+1,h+top+1,cmp); // edit 1: cmp
    }
    int x=h[1],ans=0;
    for(int i=0;i<(int)a[x].size();++i)
        ans=add(ans,mul(mul(w,fpow(i+w,mod-2)),a[x][i]));
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/autoint/p/12143069.html