LOJ # 3045. "ZJOI2019"스위치

불멸의 제목

BIG 번호 3045

\ (P = \ 합 p_i \)

제 들어 \ (I \) 위치를 고려 \ N- (\) 지수 함수를 생성하도록 구성되는 시간 후 유효 확률 \ (F_i (X) \)

\ [{} 배향을 시작 \ F_i (X) = \ sum_ {J \ BMOD 2 = s_i} \ 좌회전 (p_i \ 위에 P \ 오른쪽) ^ X ^ {J J \ 위에 J!} = {\\ & E ^ {p_ix \ 위에 P} + (- 1) ^ {s_i} ^ {E - p_ix \ 위에 P} \ \\} 2 위에 \ 단부 정렬 {} \]

총 확률 그래서 \ (EGF는 \) 입니다

(- 1) ^ {s_i} E ^ {- p_ix \ 위에 P} \ 위에 \ [{정렬}을 시작 \ F (x)는 = \ prod_ ^ N {E ^ {p_ix \ 위에 P} + {난 = 1} {] \} 배향 2} \ 단부

여기서, 그러나, 마무리 할 수있다 \ (\ n)를 최종 상태에 도달하는 단계 이전에,이 상황이 제 도달 종료 상태 이후에 고려 될 수 있고, 링의 수는 최종 상태로 되돌아 갈

우리는 걸어 고려 (n \) \ 가능성의 시작 지점으로 단계 다시

\ [{정렬}을 시작 \ G (X) = \ prod_ {I = 1} ^ N {E ^ {p_ix \ 위에 P} + E ^ {- p_ix \ 위에 P} \ 2 위에} \ 단부 {정렬} \ ]

주문 \ (H (X) \) 나타내는 응답 생성 기능하므로 이러한 세 가지 기능을하는 것이 \ (\ OGF의) 이다 \ (F, G, H \) , 거기

\ [{} 배향 H (x)는 G (X) = F (x)는 \\ H (X) = {F (X) \ 위에 g (X)} \ {단부 정렬을} \ 시작 \]

이후 \ (H (X) \) 인 확률 생성 함수, 응답이되도록 \ (H '(1) \ )

때문에

\ [\ {} 배향 H '(X) = {F'(x)는 G (X) -g '(x)는 F (X) \ 위에 g ^ 2 (X)} \ {단부 정렬을} \ 시작]

우리는 \ (F (X)는 \) 형태로 작성

\ [\ 시작 {} 배향 F (X) = \ sum_ {I} = -P ^ P의 a_ie ^ {IX \ 위에 P} \ {단부 정렬} \]

이어서 대응 \ (F (X)는 \)

\ [\ 시작 {} 배향 F (X) = \ sum_ {I} = -P ^ P의 A_I {1 \ {1- 위에 IX \ 위에 P}} \ {단부 정렬} \]

그러나 발견 때 \ (X = 1 \)\ (F (X) \)\ (g (X) \) 하지 수렴 (사용하지 \ (I = P \) 위로 때 폼의 점수 {1 \ (\ 0} 위에 \) ), 우리가 필요하므로에 \ (F (X) \)\ ((X) \) g 동시에 승산 (\ prod_는 {I 1 = \ } ^ n \ 좌측 (1- {IX \ P} 이상 \ 오른쪽) \) ,이 답변에 영향을주지 않습니다. 이때, \ (F (X)는 \)

\ [{{} 배향 F (X) = \ sum_ {I} = -P ^ P A_I \ {prod_ J \ NEQ I} \ 좌회전 ({1- {JX \ 위에 P}} \ 오른쪽) \ 단부 시작 \ 정렬} \]

경우 \ (X = 1 \) 의 후방 \ (j = P \)를 다시 초래할 수있다 (\ 0) \ , 그래요

\ [\ 시작 {} 배향 F (1) = a_P \ {prod_ J \ NEQ P} \ 좌회전 ({1- {JX \ 위에 P}} \ 오른쪽) \ {단부 정렬} \]

를 들어 \ (F '(X) \) 때문에

\ [정렬 시작 \ {} \ = (\ prod_i (1 + a_ix) \ 오른쪽) '왼쪽 \ sum_i A_I \ {prod_ J \ NEQ I} (1 + a_jx) \ {단부 정렬} \]

우리는 \ (F '(X) \ ) 개의 부분 계산 부로 나누어 \ (I \ NEQ P \) , 거기

\ [{정렬} A (X) = \ sum_ {I \ NEQ P} A_I \ sum_ {K \ NEQ I} \ 좌회전 (-k \ 위에 P \ 오른쪽) \ prod_ {J \ NEQ I, J를 시작 \ \ NEQ K} \ 좌측 (1- {JX \ 위에 P} \ 오른쪽) \ {단부 정렬} \]

경우 \ (X = 1 \)\ (K \ NEQ P \) 뒤에 때 \ (0 \) 때문에

\ [{정렬}을 시작 \ A (1) = - \ sum_ {I \ NEQ P} A_I \ prod_ {J \ NEQ I, J \ NEQ의 P} \ 좌측 (1- {J \ 위에 P} \ 오른쪽) \ END] \ {} 배향

백 동안 은 (i = P를 \) \ 이 부

\ [이 {정렬} B (1) = a_P \ sum_ {I \ NEQ P} \ 좌측을 시작 \ (- {I \ P 위에} \ 오른쪽) \ prod_ {J \ NEQ I, J \ NEQ의 P} \ 좌회전 ( 1- {J \ 위에 P} \ 오른쪽) \ {단부 정렬} \]

그래서

\ [{} 배향 F '(1) = 시작 \ A (1) + B (1) = \\ 및 - \ {prod_ I \ NEQ P} \ 좌측 (1- \ FRAC {I} {P} \ 오른쪽) \ 좌측 (\ sum_ {J \ NEQ P} \ {FRAC a_j} {1- \ FRAC {J} {P}} + a_P \ sum_ {J \ NEQ P} \ {FRAC \ FRAC {J} {P }} {1- \ FRAC {J} {P}} \ 오른쪽) \ {단부 정렬} \]

\ (g '(x)는 \ ) 와 마찬가지로 직접적으로 대체 될 수있다

당신이 단순화하기 위해 계속 수 있지만 난 정말 뒤에를 이해하지 못하고 있다고한다

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=998244353,inv2=(P+1)>>1;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int inc(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
    R int res=1;
    for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    return res;
}
const int N=5e4+5;
int f[N<<1],g[N<<1],tmp[N<<1],s[N],p[N],n,res,sum;
inline int calc(int *f){
    R int res=1,ism=ksm(sum,P-2);
    fp(i,-sum,sum-1){
        R int iv=mul(inc(i,P),ism);
        res=mul(res,P+1-iv);
    }
    return mul(res,f[sum+N]);
}
inline int dir(int *f){
    R int res=1,ret=0,ism=ksm(sum,P-2);
    fp(i,-sum,sum-1){
        R int iv=mul(inc(i,P),ism);
        res=mul(res,P+1-iv);
        upd(ret,mul(ksm(P+1-iv,P-2),inc(f[i+N],mul(f[sum+N],iv))));
    }
    return inc(0,P-mul(res,ret));
}
int main(){
//  freopen("testdata.in","r",stdin);
    scanf("%d",&n);
    fp(i,1,n)scanf("%d",&s[i]);
    fp(i,1,n)scanf("%d",&p[i]);
    f[N]=g[N]=1;
    fp(i,1,n){
        R int v=p[i];
        sum+=v;
        fp(j,-sum,sum)tmp[j+N]=0;
        R int c1=inv2,c2=s[i]?P-inv2:inv2;
        fp(j,-sum+v,sum)upd(tmp[j+N],mul(c1,f[j+N-v]));
        fd(j,sum-v,-sum)upd(tmp[j+N],mul(c2,f[j+N+v]));
        fp(j,-sum,sum)f[j+N]=tmp[j+N],tmp[j+N]=0;
        fp(j,-sum+v,sum)upd(tmp[j+N],mul(c1,g[j+N-v]));
        fd(j,sum-v,-sum)upd(tmp[j+N],mul(c1,g[j+N+v]));
        fp(j,-sum,sum)g[j+N]=tmp[j+N];
    }
    R int res=calc(g);
    res=ksm(res,P-2),res=mul(res,res);
    res=mul(res,inc(mul(dir(f),calc(g)),P-mul(dir(g),calc(f))));
    printf("%d\n",res);
    return 0;
}

추천

출처www.cnblogs.com/yuanquming/p/12056239.html