「PKUWC 2018」随机算法 (60分部分分做法)

明天就是CTSC的DAY 2了qwq,晚上敲敲暴力攒攒RP,果断随便看了个题就是打暴力hhhhh
前50% O(3^N) 暴力没什么好说的,我们设F[S][s]为已经选了S集合中的点,并且这个集合中的点的最大独立集是s的方案数,最后统计完了乘上 n! 的逆元就好了。 (s肯定是S的一个子集,所以复杂度是 3^n)
然鹅中间的暴力分只会链。。。。。
首先如果n是奇数的话,那么最大独立集只可能是所有奇数点,所有这种情况下我们知道了选了的点的集合就知道独立集是什么了,所以可以直接 O(2^n) dp了。。。。
但是出题人并没有这么良心2333,这一个点的n在最后的数据里是偶数。。。。
考虑如果n是偶数的情况的话,独立集只可能是:全是奇数的点 或者 全是偶数的点 或者 ∑ [i是偶数] <=i的全是奇数的点 和 >i的全是偶数的点,这样的话我们先用 与求n是奇数的同样的方法 (钦定最大独立集是所有奇数点) 求出对于每个偶数i,最大独立集是<=i的奇数的点的答案,然后卷积合并一下就好啦,因为后面的全是偶数的点的集合可以看成是反向的全是奇数的点的集合。
合并的时候还要乘上一个组合数,因为两边元素之间的顺序还没有确定、
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=300005,ha=998244353;
inline int add(int &x,int y){ x+=y; if(x>=ha) x-=ha;}
inline int ksm(int x,int y){ int an=1; for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha; return an;}
unordered_map<int,int> f[maxn];
unordered_map<int,int>:: iterator it;
int n,ci[35],m,uu,vv,BC[maxn],ans,M;
bool G[35][35],can[maxn][23];
inline int ADD(int S,int x){ return can[S][x]?(S|ci[x]):S;}
int g[maxn*4+5],jc[233],C[233][233]; inline void init(){
for(int i=0;i<ci[n];i++)
for(int j=0;j<n;j++) if(!(ci[j]&i)){
can[i][j]=1;
for(int o=0;o<n;o++) if((ci[o]&i)&&G[o][j]){
can[i][j]=0;
break;
} }
} inline void calc(){
ans=ans*(ll)ksm(jc[n],ha-2)%ha;
} inline void solve(){
f[0][0]=1; int all=ci[n]-1; for(int i=0;i<all;i++)
for(it=f[i].begin();it!=f[i].end();++it)
for(int j=0,S,to;j<n;j++) if(!(ci[j]&i)){
S=i|ci[j],to=ADD(it->first,j),M=max(M,BC[to]);
add(f[S][to],it->second);
} for(it=f[all].begin();it!=f[all].end();++it) if(BC[it->first]==M) add(ans,it->second);
} inline int get_line(int N){
memset(g,0,sizeof(g));
g[0]=1; int all=ci[N]-1; for(int i=0;i<all;i++) if(g[i])
for(int j=0;j<N;j++) if(!(ci[j]&i)){
if((j&1)&&!((i&ci[j-1])||(i&ci[j+1]))) continue; add(g[i|ci[j]],g[i]);
}
return g[all];
} inline void qwqwq(){
int o[23];
for(int i=2;i<=n;i+=2) o[i]=get_line(i);
add(ans,o[n]),add(ans,o[n]); for(int i=2;i<n;i+=2) add(ans,o[i]*(ll)o[n-i]%ha*C[n][i]%ha);
} int main(){
ci[0]=1;
for(int i=1;i<=20;i++) ci[i]=ci[i-1]<<1;
jc[0]=1;
for(int i=1;i<=20;i++) jc[i]=jc[i-1]*(ll)i%ha;
C[0][0]=1;
for(int i=1;i<=75;i++){
C[i][0]=1;
for(int j=1;j<=i;j++) add(C[i][j],C[i-1][j-1]),add(C[i][j],C[i-1][j]);
} scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d%d",&uu,&vv),G[uu-1][vv-1]=G[vv-1][uu-1]=1; if(n<=17){
for(int i=1;i<ci[n];i++) BC[i]=BC[i^(i&-i)]+1;
init(),solve();
}
else if(n&1) ans=get_line(n);
else qwqwq(); calc(); printf("%d\n",ans);
return 0;
}
「PKUWC 2018」随机算法 (60分部分分做法)的更多相关文章
- LOJ #2540. 「PKUWC 2018」随机算法(概率dp)
题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...
- 「PKUWC 2018」随机算法 (第二版,正解做法)
上一版貌似是打了 O(3 ^ N) 暴力和 一条链的情况,得了60分.... 第一次做的时候光想练一练暴力...就没去想正解,谁知道正解比暴力好写不知道多少,mmp 设 f(S) 为 选集合S中的点可 ...
- loj2540 「PKUWC 2018」随机算法
pkusc 快到了--做点题涨涨 rp. 记 \(f(S,i)\) 表示 \(S\) 这个集合是决计不能选的(要么属于独立集,要么和独立集相连),或称已经考虑了的,\(i\) 表示此集合对应的最大独立 ...
- LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)
写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...
- LOJ #2541. 「PKUWC 2018」猎人杀(容斥 , 期望dp , NTT优化)
题意 LOJ #2541. 「PKUWC 2018」猎人杀 题解 一道及其巧妙的题 , 参考了一下这位大佬的博客 ... 令 \(\displaystyle A = \sum_{i=1}^{n} w_ ...
- LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)
Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...
- loj2538 「PKUWC 2018」Slay the Spire
pkusc 快到了--做点题涨涨 rp. ref我好菜啊QAQ. 可以发现期望只是一个幌子.我们的目的是:对于所有随机的选择方法(一共 \(\binom{2n}{m}\)种),这些选择方法都最优地打出 ...
- LOJ #2537. 「PKUWC 2018」Minimax (线段树合并 优化dp)
题意 小 \(C\) 有一棵 \(n\) 个结点的有根树,根是 \(1\) 号结点,且每个结点最多有两个子结点. 定义结点 \(x\) 的权值为: 1.若 \(x\) 没有子结点,那么它的权值会在输入 ...
- 「PKUWC 2018」Minimax
传送门:Here 一道线段树合并好题 如果要维护点$ x$的信息,相当于合并$ x$的两棵子树 对于这题显然有:任何叶子节点的权值都可能出现在其祖先上 因而我们只需要在线段树合并的时候维护概率即可 我 ...
随机推荐
- Python学习3,列表
列表就是能够包含几个或者上千上万个元素,对我这种新手来说应该是最重要的了! _author_ = "Happyboy" shopping = ['Iphone','Huawei', ...
- Python学习2,小程序
今天主要就是弄懂了一个循环判 for i in [1,2]: for j in [1, 2, 3]: print(i, j) break else: print("for-j") ...
- wxPython 界面编程的有关事件
在事件处理的过程中涉及四个要素: 1.事件. 它是用户对界面的操作,在wxPython中事件被封装成事件类wx.Event及其子类,例如按钮事件类wx.CommandEvent,鼠标事件类是wx.Mo ...
- 孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase
孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase (完整学习过程屏幕记录视频地址在文末) 之前对关系型数据库的学习告一段落,虽然能力所限没有能够完全完成理想中的所有数据库操 ...
- android 在自定义的listview(有刷新加载项)列表中,数据过少时不能铺满整个屏幕时,header和footer同时显示问题
android 在自定义的listview(有刷新加载项)列表中,数据过少时,当刷新时,加载项也会显示,这是很头疼的一个问题,查阅了一些资料,总结了一个比较不错的方法: 原来代码: @Overrid ...
- Android记事本07
昨天: activity横竖屏切换的生命周期 今天: Anr异常的原因和解决方案 遇到的问题: 无.
- FileZilla修改文件大小格式
之前使用FileZilla觉得很奇怪,文件大小显示为字节格式,很不习惯. 最近发现是在这里修改. 菜单“编辑”下选择设置,选择选项“文件大小格式”,在右边选择为:“使用SI式二进制前缀.(如 1 KB ...
- ZooKeeper客户端 zkCli.sh 节点的配额设置
首先使用 zkCli.sh 连接上ZooKeeper服务器 配额设置命令格式如下: setquota -n|-b val path -n:val设置子节点个数 -b:val设置节点的数据长度 如果我们 ...
- 【bzoj3866】The Romantic Hero dp
题目描述 给你n个数,从中选出两个不相交非空集合S和T,使得S中的每一个元素都在T集合的前面,并且S集合中的所有数的亦或等于T集合中的所有数的与,求方案数 mod 10^9+7. 输入 The fir ...
- Android程序猿必须警示的13个坑
Android开发中,犯错是难免的,不犯错是不正常的,但是犯了错以后,我们必须时刻谨记这些坑,避免再次被坑,下面小编整理了13个,日常工作中,比较常见且易犯的错误,分享给大家. 1.类的 ...