zoukankan      html  css  js  c++  java
  • LOJ2340 [WC2018] 州区划分 【FMT】【欧拉回路】

    题目分析:

    这题是WC的题???

     

    $g[S] = (sum_{x in S}w_x)^p$

    $h[S] = g[S]$如果$S$不是欧拉回路

    $d[S] = frac{f[S]}{g[All-S]^p}$

    $f[S] = sum_{T subset S}d[S-T]*h[T]$

    总数等于$f[All]$

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 22;
      5 const int mod = 998244353;
      6 
      7 int n,m,p,f[maxn][(1<<21)+5],g[(1<<21)+5],d[maxn][(1<<21)+5],ng[maxn][maxn];
      8 int iv[(1<<21)+5],popcnt[(1<<21)+5],w[maxn];
      9 
     10 int fast_pow(int now,int pw){
     11     int ans = 1,dt = now,bit = 1;
     12     while(bit <= pw){
     13     if(bit & pw){ans = 1ll*ans*dt%mod;}
     14     dt = 1ll*dt*dt%mod; bit<<=1;
     15     }
     16     return ans;
     17 }
     18 
     19 void read(){
     20     scanf("%d%d%d",&n,&m,&p);
     21     for(int i=1;i<(1<<n);i++) popcnt[i] = popcnt[i>>1]+(i&1);
     22     for(int i=1;i<=m;i++){
     23     int u,v; scanf("%d%d",&u,&v);
     24     ng[u][v] = ng[v][u] = 1;
     25     }
     26     for(int i=1;i<=n;i++) scanf("%d",&w[i]);
     27 }
     28 
     29 void dp(int now){
     30     if(g[now] || now == 0) return;
     31     dp(now-(now&-now));
     32     g[now] = g[now-(now&-now)];
     33     for(int i=1;i<=n;i++) if((1<<i-1)&(now&-now)) g[now] += w[i];
     34 }
     35 
     36 queue<int> q;int arr[maxn];
     37 int chk(int now){
     38     for(int i=0;i<n;i++) if(now&(1<<i)){arr[i+1]=now;q.push(i+1);break;}
     39     while(!q.empty()){
     40     int k = q.front();q.pop();
     41     for(int i=1;i<=n;i++){
     42         if(!(now&(1<<i-1)) || !ng[k][i] || arr[i]==now) continue;
     43         arr[i] = now; q.push(i);
     44     }
     45     }
     46     for(int i=1;i<=n;i++) if(now&(1<<i-1)) if(arr[i]!=now) return 0;
     47     for(int i=1;i<=n;i++){
     48     if(!(now&(1<<i-1))) continue;
     49     int cnt = 0;
     50     for(int j=1;j<=n;j++){if((now&(1<<j-1))&&ng[i][j]) cnt++;}
     51     if(cnt & 1) return 0;
     52     }
     53     return 1;
     54 }
     55 
     56 void FMT(int *A){
     57     for(int i=1;i<(1<<n);i<<=1)
     58     for(int j=0;j<(1<<n);j+=(i<<1))
     59         for(int k=0;k<i;k++) {
     60         A[j+k+i] += A[j+k];
     61         if(A[j+k+i] >= mod) A[j+k+i] -= mod;
     62         }
     63 }
     64 
     65 void IFMT(int *A){
     66     for(int i=(1<<n-1);i>=1;i>>=1)
     67     for(int j=0;j<(1<<n);j+=(i<<1))
     68         for(int k=0;k<i;k++){
     69         A[j+k+i] -= A[j+k];
     70         if(A[j+k+i] < 0) A[j+k+i] += mod;
     71         }
     72 }
     73 
     74 void init(){
     75     for(int i=1;i<(1<<n);i++) dp(i);
     76     for(int i=1;i<(1<<n);i++){if(p==0)g[i]=1;else if(p==2)g[i]=g[i]*g[i];}
     77     for(int i=1;i<(1<<n);i++) iv[i] = fast_pow(g[i],mod-2);
     78     for(int i=1;i<(1<<n);i++){
     79     if(chk(i)) continue; // if it's Euler Graph
     80     int z = 0,p = i; while(p) {if(p&1)z++;p>>=1;}
     81     d[z][i] = g[i];
     82     }
     83     for(int i=1;i<=n;i++)
     84     FMT(d[i]);
     85     for(int i=0;i<(1<<n);i++) f[0][i] = iv[(1<<n)-1];
     86 }
     87 
     88 void work(){
     89     for(int i=2;i<=n;i++){
     90     for(int j=0;j<i;j++){
     91         for(int k=0;k<(1<<n);k++){
     92         f[i][k] += 1ll*f[j][k]*d[i-j][k]%mod;
     93         if(f[i][k] >= mod) f[i][k] -= mod;
     94         }
     95     }
     96     IFMT(f[i]);
     97     if(i < n){
     98         for(int j=0;j<(1<<n);j++){
     99         if(popcnt[j] != i) f[i][j] = 0;
    100         else{f[i][j] = 1ll*f[i][j]*iv[(1<<n)-j-1]%mod;}
    101         }
    102         FMT(f[i]);
    103     }
    104     }
    105     printf("%d
    ",f[n][(1<<n)-1]);
    106 }
    107 
    108 int main(){
    109     read();
    110     init();
    111     work();
    112     return 0;
    113 }
  • 相关阅读:
    C#SortedList排序列表怎么样逆序输出
    使 SortList 实现重复键排序
    【转】delphi程序只允许运行一个实例的三种方法:
    Delphi中控制Excel(转载)
    spring和hibernate的集成
    使用Jedis操作redis
    使用java发送邮件
    error at ::0 can't find referenced pointcut...解决方法
    log4j简单的使用
    spring学习笔记三:Component注解(把POJO类实例化到spring的IOC容器中)
  • 原文地址:https://www.cnblogs.com/Menhera/p/10288391.html
Copyright © 2011-2022 走看看