ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luogu P4547 [THUWC2017]随机二分图

2022-07-16 22:02:33  阅读:135  来源: 互联网

标签:THUWC2017 int luogu ll P4547 Ans 匹配 define mod


题面传送门

首先根据期望的线性性,我们可以求出每一个完美匹配出现的概率然后求和即为完美匹配个数的期望。

显然的,我们可以设\(dp_{a,b}\)表示左部点选择了\(a\)集合内的点,右部点选择了\(b\)集合内的点在完美匹配中的概率。加入\(op=0\)的边以后,分这条边出现和不出现两种情况。而且出现再分在不在完美匹配中讨论,如果两条边同时出现或不出现,可以继续分类讨论,时间复杂度\(O(2^{2n}m)\)。

可以发现左部点和右部点出现次数应该是一样的,所以总状态应该是\(\sum\limits_{i=0}^{n}(C_{n}^{i})^2=C_{2n}^{n}\leq 1.6\times 10^8\),但是再乘\(m\)显然没法接受。

考虑优化状态数,我们发现一条边没出现和一条边出现了但是没有被选入答案的效果是一样的,因此我们可以只看一条边是否出现并被选入答案。对于一类边,我们发现如果将这两条边看成独立的,如果两条边都被选入答案,贡献会减少\(25\%\),因此我们应该加入一种转移,同时加入这两条边且贡献补齐\(25\%\)。同理对于三类边,应该降低\(25\%\)才是。

为了顺序无关,我们每次钦定最小的点跑一个匹配。这样状态数就变成了\(O(C_{2n}^{n})\)。写个记搜就能跑了。

code:

#include<bits/stdc++.h>
#include<ios>
#define I inline
#define ll long long
#define db int
#define lb long db
#define N (100000+5)
#define M ((1<<10)+5)
#define K ((1<<15)+5)
#define mod 100000007
#define Mod (mod-1)
#define eps (1e-5)
#define ull unsigned ll
#define it iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x)/2)
#define Mc(x,y) memcpy(y,x,sizeof(x))
#define d(x,y) ((k+1)*(x)+(y))
#define R(n) (1ll*rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
#define UB lower_bound
#define while if
#define LB upper_bound
#define PB push_back
using namespace std;struct Edge{int x,w;};vector<Edge> S[N];unordered_map<int,int> F;
int n,m,k,op,x,y,l,r,Ct,a,b;const int Inv2=(mod+1)/2;
I void Bmod(ll &x,ll y){(x+=y)>=mod&&(x-=mod);}
I ll mpow(ll x,int y=mod-2){ll Ans=1;while(y) y&1&&(Ans=Ans*x%mod),y>>=1,x=x*x%mod;return Ans;}
I ll calc(int x){
	if(F.count(x)) return F[x];if(x==(1<<n+n)-1) return 1;ll ToT=0,y;for(int i=1;i<=n;i++) if(!(x>>(i-1)&1)){y=i;break;}
	for(Edge i:S[y]) !(x&i.x)&&(ToT+=calc(x|i.x)*i.w%mod);return F[x]=ToT%mod;
}
int main(){
	freopen("random.in","r",stdin);freopen("random.out","w",stdout);
	int i,j;scanf("%d%d",&n,&m);for(i=1;i<=m;i++){scanf("%d%d%d",&op,&l,&r);a=(1<<l-1)|(1<<r+n-1);S[l].PB((Edge){a,1});if(!op)continue;scanf("%d%d",&x,&y);b=(1<<x-1)|(1<<y+n-1);S[x].PB((Edge){b,1});!(a&b)&&(S[min(x,l)].PB((Edge){a|b,op^2?1:mod-1}),0); }
	printf("%lld\n",calc(0));
}

标签:THUWC2017,int,luogu,ll,P4547,Ans,匹配,define,mod
来源: https://www.cnblogs.com/275307894a/p/16485370.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有