• 模拟30,树


    期望可加性:对于难以整体求解的拆分。

    期望的代价、次数可以抽象为实际平均。

    代价有可加性,因为E(a->c)=E(a->b)+E(b->c);

    高斯消元是消除环的影响和期望经过次数的相互联系。

    但是复杂度过高。n^3

    所以在有可加性时要先想拆分,移项化柿子。

    移项化柿子一般出现在具有拓扑结构。

    定义两个柿子:fx表示自己走到父节点期望步数,gx表示父节点走到自己期望步数。

    通过与父节点,子节点的关系即可写出转移。注意期望的转移狮子里很可能有自己的贡献。

    f[x]=1/dux+sigma(1+fson+fx)/du;

    g[x]=1/dufa+(1+gfa+gx)/dufa+sigma(1+fother+gx)/dufa;

    再化简,发现是整数。所以不用逆元。

    维护前缀和,可以求出lca后o(1)算。(倍增非常没必要)

    #include<bits/stdc++.h>
    #define F(i,a,b) for(rg int i=a;i<=b;++i)
    #define rg register 
    #define LL long long
    #define il inline
    #define pf(a) printf("%lld ",a)
    #define phn puts("")
    using namespace std;
    #define int LL
    int read();
    /*
    状态设计:成环使首尾相连
    为何连成环?
    单纯链式地跑,状态是无限的。
    但是因为状态是首位相接的,所以可以连成环,在环上可以无限地跑
    最终状态是f(0,m),而不是f(0,0).(0,m)没开始,(0,0)已开始。
    处理环:1、高斯消元。但是是取模意义下的,而且复杂度太大会T
        2、系数递推。相当于手动高斯了。因为to(i,j)一定比当前多,可以先处理出来,就成了常量。
        而环的问题可以写出a*f0+b=fm,fm=f0+1;手动解。
        可行性在于每个状态转移来的未知量只有一个。
    to(i,j)函数:s+(1<<x),而不是((s>>x)+1)<<x,这会消去后面的x位1;
    写时仔细想想。写完把函数逐一测一测。
    */
    int n,m;
    int p[30],q[30];
    int f[420010][70];
    const int mod=2000000011,inv3=1333333341;
    il int qpow(int x,int k){int s=1;for(;k;k>>=1,x=x*x%mod)if(k&1)s=s*x%mod;return s;}
    il int cal(int s,int i){
        return ((s>>((i-1)<<1))&3)*1333333341%mod;
    }
    il int to(int s,int i){
        return s+(1<<((i-1)<<1));
    }
    int a[70],b[70];
    il int MO(int x){return x<mod?x:x-mod;}
    signed main(){
    //    freopen("ex_card2.in","r",stdin);
        n=read();m=read();
        p[0]=q[0]=100*n;int bas=qpow(100*n,mod-2);
        F(i,1,n)p[0]-=(p[i]=read()),p[i]=p[i]*bas%mod;
        F(i,1,n)q[0]-=(q[i]=read()),q[i]=q[i]*bas%mod;
        p[0]=p[0]*bas%mod;q[0]=q[0]*bas%mod;
        int mx=(1<<n*2)-1;
        for(rg int s=mx-1;~s;--s){
            F(k,0,m)a[k]=p[0],b[k]=0;
            a[m-1]=q[0];a[m]=0; 
            F(i,1,n){
                a[m-1]=MO(a[m-1]+q[i]*cal(s,i)%mod);
                if(1-cal(s,i))
                b[m-1]=MO(b[m-1]+q[i]*(1-cal(s,i)+mod)%mod*f[to(s,i)][m]%mod);
            }
            for(rg int k=m-2;k>=0;--k){
                F(i,1,n){
                    a[k]=MO(a[k]+p[i]*cal(s,i)%mod);
                    if(1-cal(s,i))
                    b[k]=MO(b[k]+p[i]*(1-cal(s,i)+mod)%mod*f[to(s,i)][k+1]%mod);
                }
                b[k]=MO(a[k]*b[k+1]%mod+b[k]);
                a[k]=a[k]*a[k+1]%mod;
            }
            f[s][m]=(b[0]+1)*qpow((1ll-a[0]+mod)%mod,mod-2)%mod;
            for(rg int k=m-1;k>=0;--k){
                f[s][k]=MO(a[k]*f[s][m]%mod+b[k]);
            }
        }
    //    pf(f[6]);
        printf("%lld
    ",f[0][m]);
    }
    il int read(){
        int s=0;char ch;
        while(ch=getchar(),!isdigit(ch));
        for(;isdigit(ch);s=s*10+(ch^48),ch=getchar());
        return s;
    }
    /*
    g++ 1.cpp -g
    time ./a.out
    1 1
    27 74
    
    2 1
    84 84
    54 54
    
    1 1
    27 74
    */
    /*
    int pc=q[0],s=1;
            F(j,1,n){
                pc=(pc+q[j]*cal(i,j)%mod)%mod;
                s=(s+(1ll-cal(i,j)+mod)*q[j]%mod*f[to(i,j)]%mod)%mod;        
            }
            f[i]=s*qpow((1ll-pc+mod)%mod,mod-2)%mod;
        //    pf(i);pf(f[i]);phn;
    */
    View Code
    Informatik verbindet dich und mich. 信息将你我连结。
  • 相关阅读:
    DFS(深度优先搜索)
    dp动态规划 之 背包问题
    python选择排序的实现
    python冒泡排序实现
    python 数据类型
    SyntaxError: Missing parentheses in call to 'print'
    MFC位图传送错误之一
    SyntaxError :invalid syntax
    Python之命令行参数
    Python之print
  • 原文地址:https://www.cnblogs.com/seamtn/p/11401701.html
Copyright © 2020-2023  润新知