zoukankan      html  css  js  c++  java
  • 解题:WC 2018 州区划分

    题面

    WC之前写的,补一补,但是基本就是学新知识了

    首先可以枚举子集$3^n$转移,优化是额外记录每个集合选取的个数,然后按照选取个数从小到大转移。转移的时候先FWT成“点值”转移完了IFWT回去乘逆元

    沙茶博主也不知道为什么这样就是对的,放个没看懂的yww大佬的博客

     1 // luogu-judger-enable-o2
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=22,M=(1<<N)+N,K=110,mod=998244353;
     7 int mat[N][N],val[N],aset[N],deg[N],inv[N*K];
     8 int sum[M],gain[N][M],dp[N][M],bit[M];
     9 int n,m,p,t1,t2,all,lth;
    10 void Mod(int &x,int y)
    11 {
    12     x+=y;
    13     if(x<0) x+=mod;
    14     if(x>=mod) x-=mod;
    15 }
    16 int S(int x)
    17 {
    18     return 1<<(x-1);
    19 }
    20 int Val(int x)
    21 {
    22     return p?(p==1?x:1ll*x*x%mod):1;
    23 }
    24 int Finda(int x)
    25 {
    26     return aset[x]==x?x:aset[x]=Finda(aset[x]);
    27 }
    28 int Calc(int sta)
    29 {
    30     register int i,j;
    31     int abe=0,nde=0;
    32     for(i=1;i<=n;deg[i]=0,i++)
    33         if(sta&S(i)) aset[i]=i;
    34     for(i=1;i<=n;i++)
    35         if(sta&S(i))
    36         {
    37             nde=i,sum[sta]+=val[i];
    38             for(j=1;j<=n;j++)
    39                 if((sta&S(j))&&mat[i][j]) 
    40                     deg[i]++,aset[Finda(j)]=Finda(i);
    41             if(deg[i]%2) abe=1;
    42         }
    43     int anc=Finda(nde);
    44     for(i=1;i<=n;i++) 
    45         if(sta&S(i)) abe|=Finda(i)!=anc; 
    46     return abe*Val(sum[sta]);
    47 }
    48 void Trans(int *arr,int len,int typ)
    49 {
    50     register int i,j,k;
    51     for(i=2;i<=len;i<<=1)
    52     {
    53         int lth=i>>1;
    54         for(j=0;j<len;j+=i)
    55             for(k=j;k<j+lth;k++)
    56                 Mod(arr[k+lth],typ*arr[k]);
    57     }
    58 }
    59 void Pre()
    60 {
    61     register int i;
    62     scanf("%d%d%d",&n,&m,&p),lth=1<<n,all=lth-1;
    63     for(i=1;i<=m;i++)
    64     {
    65         scanf("%d%d",&t1,&t2);
    66         mat[t1][t2]=mat[t2][t1]=true;
    67     }
    68     for(i=1;i<=n;i++) scanf("%d",&val[i]);
    69     dp[0][0]=1,inv[1]=1,Trans(dp[0],lth,1);
    70     for(i=2;i<=2100;i++)
    71         inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    72     for(i=0;i<=all;i++)
    73         bit[i]=bit[i>>1]+(i&1),gain[bit[i]][i]=Calc(i);
    74     for(i=0;i<=n;i++) Trans(gain[i],lth,1);
    75 }
    76 int main()
    77 {
    78     Pre();
    79     register int i,j,k;
    80     for(i=1;i<=n;i++)
    81     {
    82         for(j=0;j<=i;j++)
    83             for(k=0;k<=all;k++)
    84                 Mod(dp[i][k],1ll*dp[j][k]*gain[i-j][k]%mod);
    85         Trans(dp[i],lth,-1);
    86         for(int j=0;j<=all;j++)
    87             dp[i][j]=(bit[j]==i)?1ll*dp[i][j]*Val(inv[sum[j]])%mod:0;
    88         if(i!=n) Trans(dp[i],lth,1);
    89     }
    90     printf("%d",dp[n][all]);
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    Html5响应式设计与实现广场
    hdu 4911 Inversion
    LAN远程重启server安全方法
    华丽的网上突出代码组件CodeMirror
    Edit Distance -- LeetCode
    FPGA合成编码
    SenchaTouch2.3.1 正在使用listpaging以及pullrefresh插入 分页演示样品做
    【白云观导引头】一首诗
    初步boost之pool图书馆学习笔记
    分段的作用
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10414949.html
Copyright © 2011-2022 走看看