loj#2340. 「WC2018」州区划分
FWT&&FMT板子

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int _=1e2;
const int maxn=+;
const int fbin=(<<)+_;
const LL mod=;
LL quick_pow(LL A,int p)
{
LL ret=;
while(p!=)
{
if(p%==)ret=ret*A%mod;
A=A*A%mod;p/=;
}
return ret;
} //--------------------------------------------------def-------------------------------------------------------- struct node
{
int x,y,next;
}a[maxn*maxn];int len,last[maxn];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int w[maxn],du[maxn];
int fa[maxn];
int findfa(int x)
{
if(x==fa[x])return x;
fa[x]=findfa(fa[x]);return fa[x];
} //--------------------------------------------pre-------------------------------------------------------------- int cnt[fbin];
LL h[fbin],g[maxn][fbin],f[maxn][fbin];
void FWT(LL *a,int n,int op)
{
for(int i=;i<n;i<<=)
for(int j=;j<n;j+=(i<<))
for(int k=;k<i;k++)
if(op==)a[j+k+i]=(a[j+k+i]+a[j+k])%mod;
else a[j+k+i]=(a[j+k+i]-a[j+k]+mod)%mod;
}
int main()
{
int n,li,m,p,x,y;
scanf("%d%d%d",&n,&m,&p); li=(<<n);
len=;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
ins(x,y),ins(y,x);
}
for(int i=;i<=n;i++)scanf("%d",&w[i]);
for(int zt=;zt<li;zt++)
{
for(int i=;i<=n;i++)
if((<<(i-))&zt)h[zt]+=w[i],cnt[zt]++;
h[zt]=quick_pow(quick_pow(h[zt],mod-),p); bool bk=true;
memset(du,,sizeof(du));
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=len;i+=)
if( ((<<(a[i].x-))&zt) && ((<<(a[i].y-))&zt) )
du[a[i].x]++,du[a[i].y]++,fa[findfa(a[i].x)]=fa[findfa(a[i].y)];
int rt=;
for(int i=;i<=n;i++)
{
if(du[i]%==){bk=false;break;}
if((<<(i-))&zt)
{
if(rt==)rt=findfa(i);
else if(rt!=findfa(i)){bk=false;break;}
}
}
if(bk==false)
{
for(int i=;i<=n;i++)
if((<<(i-))&zt)g[cnt[zt]][zt]+=w[i];
g[cnt[zt]][zt]=quick_pow(g[cnt[zt]][zt],p);
}
} //......pre......... for(int i=;i<=n;i++)FWT(g[i],li,);
f[][]=;FWT(f[],li,);
for(int i=;i<=n;i++)
{
for(int j=;j<i;j++)
for(int zt=;zt<li;zt++)
f[i][zt]=(f[i][zt]+f[j][zt]*g[i-j][zt])%mod;
FWT(f[i],li,-);
for(int zt=;zt<li;zt++)
{
if(cnt[zt]!=i)f[i][zt]=;
f[i][zt]=f[i][zt]*h[zt]%mod;
}
if(i!=n)FWT(f[i],li,);
}
printf("%lld\n",f[n][li-]); return ;
}
FWT or
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int _=1e2;
const int maxn=+;
const int fbin=(<<)+_;
const LL mod=;
const LL inv2=mod/+;
LL quick_pow(LL A,int p)
{
LL ret=;
while(p!=)
{
if(p%==)ret=ret*A%mod;
A=A*A%mod;p/=;
}
return ret;
} //--------------------------------------------------def-------------------------------------------------------- struct node
{
int x,y,next;
}a[maxn*maxn];int len,last[maxn];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int w[maxn],du[maxn];
int fa[maxn];
int findfa(int x)
{
if(x==fa[x])return x;
fa[x]=findfa(fa[x]);return fa[x];
} //--------------------------------------------pre-------------------------------------------------------------- int cnt[fbin];
LL h[fbin],g[maxn][fbin],f[maxn][fbin];
void FWT(LL *a,int n,int op)
{
for(int i=;i<n;i<<=)
for(int j=;j<n;j+=(i<<))
for(int k=;k<i;k++)
{
LL t1=a[j+k],t2=a[j+k+i];
a[j+k]=(t1+t2)%mod;
a[j+k+i]=(t1-t2+mod)%mod;
if(op==-)a[j+k]=a[j+k]*inv2%mod,a[j+k+i]=a[j+k+i]*inv2%mod;
}
}
int main()
{
int n,li,m,p,x,y;
scanf("%d%d%d",&n,&m,&p); li=(<<n);
len=;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
ins(x,y),ins(y,x);
}
for(int i=;i<=n;i++)scanf("%d",&w[i]);
for(int zt=;zt<li;zt++)
{
for(int i=;i<=n;i++)
if((<<(i-))&zt)h[zt]+=w[i],cnt[zt]++;
h[zt]=quick_pow(quick_pow(h[zt],mod-),p); bool bk=true;
memset(du,,sizeof(du));
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=len;i+=)
if( ((<<(a[i].x-))&zt) && ((<<(a[i].y-))&zt) )
du[a[i].x]++,du[a[i].y]++,fa[findfa(a[i].x)]=fa[findfa(a[i].y)];
int rt=;
for(int i=;i<=n;i++)
{
if(du[i]%==){bk=false;break;}
if((<<(i-))&zt)
{
if(rt==)rt=findfa(i);
else if(rt!=findfa(i)){bk=false;break;}
}
}
if(bk==false)
{
for(int i=;i<=n;i++)
if((<<(i-))&zt)g[cnt[zt]][zt]+=w[i];
g[cnt[zt]][zt]=quick_pow(g[cnt[zt]][zt],p);
}
} //......pre......... for(int i=;i<=n;i++)FWT(g[i],li,);
f[][]=;FWT(f[],li,);
for(int i=;i<=n;i++)
{
for(int j=;j<i;j++)
for(int zt=;zt<li;zt++)
f[i][zt]=(f[i][zt]+f[j][zt]*g[i-j][zt])%mod;
FWT(f[i],li,-);
for(int zt=;zt<li;zt++)
{
if(cnt[zt]!=i)f[i][zt]=;
f[i][zt]=f[i][zt]*h[zt]%mod;
}
if(i!=n)FWT(f[i],li,);
}
printf("%lld\n",f[n][li-]); return ;
}
FWT xor
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int _=1e2;
const int maxn=+;
const int fbin=(<<)+_;
const LL mod=;
const LL inv2=mod/+;
LL quick_pow(LL A,int p)
{
LL ret=;
while(p!=)
{
if(p%==)ret=ret*A%mod;
A=A*A%mod;p/=;
}
return ret;
} //--------------------------------------------------def-------------------------------------------------------- struct node
{
int x,y,next;
}a[maxn*maxn];int len,last[maxn];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int w[maxn],du[maxn];
int fa[maxn];
int findfa(int x)
{
if(x==fa[x])return x;
fa[x]=findfa(fa[x]);return fa[x];
} //--------------------------------------------pre-------------------------------------------------------------- int cnt[fbin];
LL h[fbin],g[maxn][fbin],f[maxn][fbin];
void FMT(LL *a,int n,int li,int op)
{
for(int i=;i<=n;i++)
for(int zt=;zt<li;zt++)
if((<<(i-))&zt)a[zt]=(a[zt]+op*a[zt^(<<i-)]+mod)%mod;
}
int main()
{
int n,li,m,p,x,y;
scanf("%d%d%d",&n,&m,&p); li=(<<n);
len=;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
ins(x,y),ins(y,x);
}
for(int i=;i<=n;i++)scanf("%d",&w[i]);
for(int zt=;zt<li;zt++)
{
for(int i=;i<=n;i++)
if((<<(i-))&zt)h[zt]+=w[i],cnt[zt]++;
h[zt]=quick_pow(quick_pow(h[zt],mod-),p); bool bk=true;
memset(du,,sizeof(du));
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=len;i+=)
if( ((<<(a[i].x-))&zt) && ((<<(a[i].y-))&zt) )
du[a[i].x]++,du[a[i].y]++,fa[findfa(a[i].x)]=fa[findfa(a[i].y)];
int rt=;
for(int i=;i<=n;i++)
{
if(du[i]%==){bk=false;break;}
if((<<(i-))&zt)
{
if(rt==)rt=findfa(i);
else if(rt!=findfa(i)){bk=false;break;}
}
}
if(bk==false)
{
for(int i=;i<=n;i++)
if((<<(i-))&zt)g[cnt[zt]][zt]+=w[i];
g[cnt[zt]][zt]=quick_pow(g[cnt[zt]][zt],p);
}
} //......pre......... for(int i=;i<=n;i++)FMT(g[i],n,li,);
f[][]=;FMT(f[],n,li,);
for(int i=;i<=n;i++)
{
for(int j=;j<i;j++)
for(int zt=;zt<li;zt++)
f[i][zt]=(f[i][zt]+f[j][zt]*g[i-j][zt])%mod;
FMT(f[i],n,li,-);
for(int zt=;zt<li;zt++)
{
if(cnt[zt]!=i)f[i][zt]=;
f[i][zt]=f[i][zt]*h[zt]%mod;
}
if(i!=n)FMT(f[i],n,li,);
}
printf("%lld\n",f[n][li-]); return ;
}
loj#2340. 「WC2018」州区划分的更多相关文章
- 【LOJ】#2340. 「WC2018」州区划分
题解 学习一个全世界人都会只有我不会的东西 子集变换! 难道我要把这题当板子讲?等等这题好像是板...WC出板题好刺激啊= = 假装我们都做过HAOI2015的FMT题,我们都知道一些FMT怎么解决或 ...
- 「WC2018」州区划分(FWT)
「WC2018」州区划分(FWT) 我去弄了一个升级版的博客主题,比以前好看多了.感谢 @Wider 不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了. ...
- LOJ 2339 「WC2018」通道——边分治+虚树
题目:https://loj.ac/problem/2339 两棵树的话,可以用 CTSC2018 暴力写挂的方法,边分治+虚树.O(nlogn). 考虑怎么在这个方法上再加一棵树.发现很难弄. 看了 ...
- @loj - 2339@ 「WC2018」通道
目录 @desription@ @solution@ @accepted code@ @details@ @desription@ 11328 年,C 国的科学家们研发了一种高速传送通道,可以在很短的 ...
- Loj #3056. 「HNOI2019」多边形
Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...
- Loj #3042. 「ZJOI2019」麻将
Loj #3042. 「ZJOI2019」麻将 题目描述 九条可怜是一个热爱打麻将的女孩子.因此她出了一道和麻将相关的题目,希望这题不会让你对麻将的热爱消失殆尽. 今天,可怜想要打麻将,但是她的朋友们 ...
- Loj #2570. 「ZJOI2017」线段树
Loj #2570. 「ZJOI2017」线段树 题目描述 线段树是九条可怜很喜欢的一个数据结构,它拥有着简单的结构.优秀的复杂度与强大的功能,因此可怜曾经花了很长时间研究线段树的一些性质. 最近可怜 ...
- loj2341「WC2018」即时战略(随机化,LCT/动态点分治)
loj2341「WC2018」即时战略(随机化,LCT/动态点分治) loj Luogu 题解时间 对于 $ datatype = 3 $ 的数据,explore操作次数只有 $ n+log n $ ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
随机推荐
- Codeforces Gym 100203G Good elements 暴力乱搞
原题链接:http://codeforces.com/gym/100203/attachments/download/1702/statements.pdf 题解 考虑暴力的复杂度是O(n^3),所以 ...
- BZOJ 2085 [POI2010] Hamsters
题面 Description Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算.现在Tz想好了要出现多 ...
- n个平面把空间最多分成几个部分?
题目: n个平面把空间最多分成几个部分? 解答: 1条直线可以把平面分成2部分,2条直线最多可以把平面分成4部分, 3条直线最多可以把平面分成几部分,4条直线呢?你能不能想出n条直线最多可以把平面分成 ...
- Go语言 -- 获取命令行参数
部署golang项目时难免要通过命令行来设置一些参数,那么在golang中如何操作命令行参数呢?可以使用flag库和os库.1.flag库的使用 Go语言标准库提供了用于快迅解析命令行参数的flag包 ...
- Linux 网卡驱动学习(二)(网络驱动接口小结)
[摘要]前文我们分析了一个虚拟硬件的网络驱动例子,从中我们看到了网络设备的一些接口,其实网络设备驱动和块设备驱动的功能比较类似,都是发送和接收数据包(数据请求).当然它们实际是有很多不同的. 1.引言 ...
- K-L变换和 主成分分析PCA
一.K-L变换 说PCA的话,必须先介绍一下K-L变换了. K-L变换是Karhunen-Loeve变换的简称,是一种特殊的正交变换.它是建立在统计特性基础上的一种变换,有的文献也称其为霍特林(Hot ...
- 算法——字符串匹配之BM算法
前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左開始比較,但模式串的移动依旧是从左到右的.在实践中.BM算法效率高于前面介绍的<KM ...
- 树莓派 Zero作为飞控图传
前言 原创文章,转载引用务必注明链接,水平有限,如有疏漏,欢迎指正. 本文使用Markdown写成,为获得更好的阅读体验和正常的链接.图片显示,请访问我的博客原文: http://www.cnblog ...
- 用DD-WRT自建计费WiFi热点
架设无线网络(Wlan)向周围的用户有偿共享网络. 传统的方法,能够使用专业的无线与宽带计费网关设备和软件.比方MikroTik等. 只是,对于个人架设WiFi热点来说.这些方案太过昂贵,安装设置也很 ...
- leetCode(40):Path Sum
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...