题目链接

题目描述

Sol

一个州合法就是州内点形成的子图中 不存在欧拉回路(一个点也算欧拉回路)。

这个东西显然就状压 dp 一下:

设 \(f[S]\) 表示当前考虑了 \(S\) 这个集合内所有点的所有方案满意度之和。

转移就枚举一个子集作为最后选出的一个州

\[f[S]=\bigg(\frac{1}{sum[S]}\bigg)^p\sum_{T\subseteq S}f[T]*g[S-T]
\]

\(sum[S]\) 表示 \(S\) 内所有城市的人口之和

\(g[S]\) 表示 , 如果 \(S\) 是一个合法的州,那么 \(g[S]=sum[S]^p\) , 否则\(g[S]=0\)

后面那个东西就是个子集卷积了,对于两个集合 \(U,V\) , 如果 \(U|V=S\) 且 \(U\&V=0\) 那么就把他们的积贡献给 \(S\) 。

如果不需要满足集合无交的化就是一个或卷积 , 直接 \(FWT\) 。

但是这里要求无交。解决方法就是按照集合大小一个个来做。

因为 如果满足 \(U|V=S\) 且 \(|U|+|V|=|S|\) 的话 那么 \(U\) 和 \(V\) 就一定无交了,这样转化为大小限制就可以通过清空不合法状态来保证正确性。

每次做完一个大小后把数组中不是当前大小的状态的值清0就可以了。

code:

  1. #include<bits/stdc++.h>
  2. #define Set(a,b) memset(a,b,sizeof(a))
  3. using namespace std;
  4. const int N=22;
  5. const int MAXN=1<<(N-1);
  6. const int mod=998244353;
  7. template <typename T> inline void init(T&x){
  8. x=0;char ch=getchar();bool t=0;
  9. for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
  10. for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
  11. if(t) x=-x;return;
  12. }typedef long long ll;
  13. template <typename T>inline void Inc(T&x,int y){x+=y;if(x>=mod) x-=mod;return;}
  14. template <typename T>inline void Dec(T&x,int y){x-=y;if(x < 0) x+=mod;return;}
  15. template <typename T>inline int fpow(int x,T k){int ret=1;for(;k;k>>=1,x=(ll)x*x%mod) if(k&1) ret=(ll)ret*x%mod;return ret;}
  16. int Sum(int x,int y){x+=y;if(x>=mod) return x-mod;return x;}
  17. int Dif(int x,int y){x-=y;if(x < 0 ) return x+mod;return x;}
  18. int n,m,p;int Ful;
  19. struct edge{
  20. int to,next;
  21. }a[N*N];int cnt=0;
  22. int head[N],sum[MAXN],Isum[MAXN],w[N],bits[N],number[MAXN];
  23. inline void add(int x,int y){a[++cnt]=(edge){y,head[x]};head[x]=cnt;}
  24. int deg[N];bool vis[N];int stk[N],top=0;
  25. int fa[N];int f[22][MAXN],g[22][MAXN];
  26. inline int find(int x){return fa[x]==x? x:fa[x]=find(fa[x]);}
  27. inline void Merge(int x,int y){int fx=find(x),fy=find(y);if(fx==fy) return;fa[fx]=fy;}
  28. namespace FST{
  29. inline void DFT(int*A,int n,int f){
  30. for(int i=1;i<n;i<<=1)
  31. for(int p=i<<1,j=0;j<n;j+=p)
  32. for(int k=0;k<i;++k)
  33. (~f)? Inc(A[i|j|k],A[j|k]):Dec(A[i|j|k],A[j|k]);
  34. return;
  35. }
  36. }
  37. int main()
  38. {
  39. init(n),init(m),init(p);int u,v;
  40. for(int i=1;i<=m;++i) {init(u),init(v);add(u,v),add(v,u);}
  41. for(int i=1;i<=n;++i) init(w[i]);sum[0]=0;
  42. Ful=(1<<n)-1;bits[0]=1;for(int i=1;i<=n;++i) bits[i]=bits[i-1]<<1;
  43. for(int i=1;i<=n;++i) fa[i]=i;
  44. for(int i=1;i<=Ful;++i) {top=0;number[i]=number[i>>1]+(i&1);
  45. for(int j=1;j<=n;++j) if(i&bits[j-1]) stk[++top]=j,vis[j]=1,Inc(sum[i],w[j]);
  46. bool fl=0;sum[i]=fpow(sum[i],p);Isum[i]=fpow(sum[i],mod-2);
  47. for(int j=1;j<=top;++j) {
  48. int u=stk[j];
  49. for(int v,i=head[u];i;i=a[i].next) {v=a[i].to;if(!vis[v]) continue;Merge(u,v);++deg[u];}
  50. if(deg[u]&1) {fl=1;break;}
  51. }int rt=find(stk[1]);
  52. for(int j=2;j<=top;++j) if(find(stk[j])!=rt) {fl=1;break;}
  53. for(int j=1;j<=top;++j) {int u=stk[j];fa[u]=u,deg[u]=0,vis[u]=0;}
  54. if(!fl) continue;g[number[i]][i]=sum[i];
  55. }f[0][0]=1;
  56. for(int i=0;i<=n;++i) FST::DFT(g[i],bits[n],1);FST::DFT(f[0],bits[n],1);
  57. for(int i=1;i<=n;++i) {
  58. for(int j=0;j<i;++j) for(int s=0;s<=Ful;++s) Inc(f[i][s],(ll)f[j][s]*g[i-j][s]%mod);
  59. FST::DFT(f[i],bits[n],-1);// IDFT
  60. for(int s=0;s<=Ful;++s) {if(number[s]!=i) f[i][s]=0;else f[i][s]=(ll)f[i][s]*Isum[s]%mod;}
  61. if(i!=n) FST::DFT(f[i],bits[n],1);
  62. }
  63. cout<<f[n][Ful]<<endl;
  64. return 0;
  65. }

【Luogu4221】[WC2018] 州区划分的更多相关文章

  1. Luogu4221 WC2018州区划分(状压dp+FWT)

    合法条件为所有划分出的子图均不存在欧拉回路或不连通,也即至少存在一个度数为奇数的点或不连通.显然可以对每个点集预处理是否合法,然后就不用管这个奇怪的条件了. 考虑状压dp.设f[S]为S集合所有划分方 ...

  2. [WC2018]州区划分——FWT+DP+FST

    题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...

  3. [WC2018]州区划分

    [WC2018]州区划分 注意审题: 1.有序选择 2.若干个州 3.贡献是州满意度的乘积 枚举最后一个州是哪一个,合法时候贡献sum[s]^p,否则贡献0 存在欧拉回路:每个点都是偶度数,且图连通( ...

  4. [UOJ#348][WC2018]州区划分

    [UOJ#348][WC2018]州区划分 试题描述 小 \(S\) 现在拥有 \(n\) 座城市,第ii座城市的人口为 \(w_i\),城市与城市之间可能有双向道路相连. 现在小 \(S\) 要将这 ...

  5. [WC2018]州区划分(FWT,FST)

    [WC2018]州区划分(FWT,FST) Luogu loj 题解时间 经典FST. 在此之前似乎用到FST的题并不多? 首先预处理一个子集是不是欧拉回路很简单,判断是否连通且度数均为偶数即可. 考 ...

  6. P4221 [WC2018]州区划分 无向图欧拉回路 FST FWT

    LINK:州区划分 把题目中四个条件进行规约 容易想到不合法当前仅当当前状态是一个无向图欧拉回路. 充要条件有两个 联通 每个点度数为偶数. 预处理出所有状态. 然后设\(f_i\)表示组成情况为i的 ...

  7. [WC2018]州区划分(FWT)

    题目描述 题解 这道题的思路感觉很妙. 题目中有一个很奇怪的不合法条件,貌似和后面做题没有什么关系,所以我们先得搞掉它. 也就是判断一个点集是否合法,也就是判断这个点集是否存在欧拉回路. 如果存在欧拉 ...

  8. 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 ...

  9. [WC2018]州区划分(状压DP+FWT/FMT)

    很裸的子集反演模板题,套上一些莫名其妙的外衣. 先预处理每个集合是否合法,再作显然的状压DP.然后发现可以写成子集反演的形式,直接套模板即可. 子集反演可以看这里. 子集反演的过程就是多设一维代表集合 ...

随机推荐

  1. springboot 使用外置tomcat启动

    pom.xml  如下 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...

  2. 二:flask-debug模式详解

    debug模式的情况下可以抛出详细异常信息 新建一个脚本并运行 访问 此时是非debug模式,如果运行的时候代码报错了,是不会提示详细错误的,只会报服务器内部错误 开启debug模式,可以查看到详细错 ...

  3. 一:flask-第一个flask程序

    安装flask:pip install flask,或者pycharm安装 最小模型 访问 后台:

  4. Linux监控命令之==>iostat

    一.使用说明 iostat 是对系统的磁盘I/O 操作进行监控,它的输出主要显示磁盘读写操作的统计信息,同时给出CPU 的使用情况.同vmstat 一样,iostat 不能对某个进程进行深入分析,仅对 ...

  5. jdk的keytool生成jks和获取jks的信息,公匙

    1.生成jks.执行命令:keytool -genkeypair -alias mytest -keyalg RSA -keypass mypass -keystore mytest.jks -sto ...

  6. Linux下安装Elasticsearch6.5

    1.安装JDK8(Elastic 需要 Java 8 环境) 1)下载jdk8文件:http://www.oracle.com/technetwork/java/javase/downloads/jd ...

  7. CSS3——边框 圆角 背景 渐变 文本效果

    边框 圆角边框 盒阴影 边界图片 圆角 CSS3 圆角制作器 指定每个角 背景 多重背景图像 大小 图像的定位 背景剪裁 渐变 线性渐变(Linear Gradients)- 向下/向上/向左/向右/ ...

  8. 剑指offer--day12

    1.1 题目:复杂链表的复制:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回 ...

  9. 【linux开发】apt源设置

    不同的网络状况连接以下源的速度不同, 建议在添加前手动验证以下源的连接速度(ping下就行),选择最快的源可以节省大批下载时间. 首先备份源列表: sudo cp /etc/apt/sources.l ...

  10. iview报错[Vue warn]: Error in render: "TypeError: ctx.injections.tableRoot.$scopedSlots[ctx.props.column.slot] is not a function"

    原因是我使用了iview的<Table>组件,我给Table组件的columns中定义了4个含有slot的列,但是实际在<Table>中只使用了其中3个,导致的报错. 也就是说 ...