zoukankan      html  css  js  c++  java
  • 【题解】小星星 [ZJOI2016] [P3349]

    【题解】小星星 [ZJOI2016] [P3349]

    传送门:小星星 ( ext{[ZJOI2016] [P3349]})

    【题目描述】

    给出 (n) 个点的一张无向图 ((V,E)) 和一颗树,现需要给每个点 (i) 安排一个映射 (a_i),满足对于树上任意边 ((x,y)),均有边 ((a_x,a_y)in E)。要求 (a) 为一个排列(即不存在两个点的映射相同),求方案数。

    【分析】

    组合意义天地灭,代数推导保平安。 —— tiger0133

    大家似乎都是直接硬找的容斥系数,这里提供一个不需要费脑子的子集反演做法(最终柿子是一样的)。

    先考虑最 ( ext{naive}) 的暴力状压:设 (dp(x,j,S)) 表示点 (x) 映射为 (j)(x) 子树内所有点已经使用了 (S) 作为映射 的方案数((S) 为一个二进制数)。

    (dp) 数组第一、三维的作用显然,第二维 (j) 是为了方便判断是否有连边。

    转移需要枚举 (S) 的子集,复杂度 (O(n^33^n)),用多项式科技优化子集卷积可以做到 (O(n^42^n)),显然还是过不了。

    复杂度瓶颈在于枚举子集,必须把这个东西去掉。

    优化子集 (dp) 显然要上容斥,不过这里我们采用另一个思路:子集反演。

    搞反演的第一步是设计两个状态,且需满足其中一个可以方便求得、另一个可以方便得出答案、两者之间存在关系式。

    设计状态用类似二项式反演的套路去思考,如果实在想不出来就一个一个枚举限制条件,逐个检验是否可行。

    本题的关键限制在于:任意两点的映射不能相同。当存在这一限制时无论怎么设都不好搞,所以设状态时需要把这个限制去掉。

    (f(S))(n) 个点的映射恰好使用了 (S) 中的所有点(无需满足 (a) 为排列)。

    (g(S))(n) 个点的映射至多只能够使用 (S) 中的点(无需满足 (a) 为排列)。

    易知:

    [g(S)=sum_{Tsubseteq S}f(T) ]

    由子集反演可得:

    [f(S)=sum_{Tsubseteq S}(-1)^{|S|-|T|}g(T) ]

    注意
    在做二项式反演时,我们所说的“至多”和“至少”都是假的,真正含义为:钦定某一部分满足某条件,其余部分随意。因此 (f,g) 的关系式中会存在一个二项式系数(一个 (f(i)) 会被 (g(x)) 统计多次,当状态只有一维时,这个次数为 (C_{i}^{x}) 或者 (C_{x}^{i}))。
    但这里子集反演定义的“至多”是真货,每个 (f(T)) 只会被 (g(S)) 统计一次,因此 (g(S)) 直接就等于 (sum_{Tsubseteq S}f(T)),不会带有奇怪的系数。

    回到这道题,最终答案为 (f(V)),其中 (V) 为全集(即 (2^{n}-1))。

    Q:为什喵?前面做定义时不是说的不一定满足 (a) 为排列吗?
    A: 由于全集 (V) 中的 (n) 个点全都被作为映射使用了,而一个点只能映射一个,所以 (f(V)) 统计的方案中每个点的映射必定两两不同。

    那么最后的问题就是 在不涉及 (f) 的情况下快速计算 (g(S)) 了。

    修改一下前面的暴力状压:

    (dp(x,j,S)) 表示点 (x) 映射为 (j)(x) 子树内所有点至多只能使用 (S) 中的点作为映射值 的方案数(无需满足映射两两不同)。

    转移为:

    [dp(x,j,S)=prodlimits_{toin{son(x)}}left(sumlimits_{ksubseteq S,(j,k)in E}dp(to,k,S) ight) ]

    可得 (g(S)=sum_{jsubseteq S}dp(rt,j,S)),其中 (rt) 为树的根。

    时间复杂度为:(O(n^32^n)),要凭信仰卡常....

    【Code】

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define Re register int
    using namespace std;
    const int N=18,M=131072+3;
    int n,m,x,y,o,V,v[N],cnt[M],head[N],A[N][N];LL ans,g[M],dp[N][N];
    struct QAQ{int to,next;}a[N<<1];
    inline void add(Re x,Re y){a[++o].to=y,a[o].next=head[x],head[x]=o;}
    inline void in(Re &x){
        int f=0;x=0;char ch=getchar();
        while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar();
        while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=f?-x:x;
    }
    inline void dfs(Re x,Re fa,Re S){
        for(Re i=1;i<=v[0];++i)dp[x][i]=1;
        for(Re i=head[x],to;i;i=a[i].next)
            if((to=a[i].to)!=fa){
                dfs(to,x,S);
                for(Re j=1;j<=v[0];++j){
                    LL tmp=0;
                    for(Re k=1;k<=v[0];++k)if(A[v[j]][v[k]])tmp+=dp[to][k];
                    dp[x][j]*=tmp;
                }
            }
    }
    int main(){
    //    freopen("123.txt","r",stdin);
        in(n),in(m),V=(1<<n)-1;
        if(n==1){puts("1");return 0;}
        while(m--)in(x),in(y),A[x][y]=A[y][x]=1;
        m=n-1;
        while(m--)in(x),in(y),add(x,y),add(y,x);
        for(Re s=0;s<=V;++s){
            cnt[s]=cnt[s>>1]+(s&1),v[0]=0;
            for(Re i=1;i<=n;++i)if(s&(1<<i-1))v[++v[0]]=i;
            dfs(1,0,s);LL g=0;
            for(Re i=1;i<=v[0];++i)g+=dp[1][i];
            ans+=(n-cnt[s]&1)?-g:g;
        }
        printf("%lld
    ",ans);
    }
    

    完结洒花花~

    ...等等,还没完!

    这题神奇地没有让取模!

    虽然答案的最大值 (n!) 没有爆 ( ext{long long}),但 (max(g(V))=n^n) 爆了啊。

    emm....手写高精多半会 ( ext{TLE}) ....就酱吧awa
    (据说用 ( ext{long long})( ext{int128}) 算出来的结果是一样的)

  • 相关阅读:
    eclipse中的Invalid text string (xxx).
    在jsp文件中出现Unknown tag (c:out)
    eclipse 界面复原
    ecilpse 纠错插件
    Multiple annotations found at this line:- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    Port 8080 required by Tomcat v9.0 Server at localhost is already in use. The server may already be running in another process, or a system process may be using the port.
    调用第三方https接口
    调用第三方http接口
    创建带值枚举
    spring整合redis之Redis配置文件
  • 原文地址:https://www.cnblogs.com/Xing-Ling/p/13373094.html
Copyright © 2011-2022 走看看