zoukankan      html  css  js  c++  java
  • THUWC2017 随机二分图

    一道神仙题
    题目链接


    这个数据很状压啊
    但是(type=2,3)的有点麻烦.
    (f[S])表示集合为(S)的完美匹配期望.
    一条边相当于一种转移.
    我们考虑把两条边分开计数,各有(50\%)的概率出现.
    假设第一条边是((u,v)),第二条边是((x,y))
    如果(type=2),那么两条边都出现的概率应该是(50\%),然而我们计算的概率是(25\%),因此我们要给整个点集加入一个(25\%)的偏移量.
    同理如果(type=3),那么两条边都出现的概率应该是(0),那么我们给整个点集加入一个(-25\%)的偏移量.
    如果这两条边有公共点,那么我们肯定无法同时选择这两条边.那么就不用加偏移量.

    然后就可以愉快地状压啦.
    状压时有一个常用的小(trick)就是钦定转移最高位来减小复杂度.
    哦还有一个问题.
    我们存不下这个(dp)值,开个(map)就好啦

    代码如下

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<bitset>
    #include<set>
    #define N (15)
    #define P (1000000007)
    #define inf (0x7f7f7f7f)
    typedef long double ld;
    typedef long long LL;
    typedef unsigned long long ull;
    using namespace std;
    namespace fastIO1{
    	inline char read(){
    		static const int IN_LEN=1000000;
    		static char buf[IN_LEN],*s,*t;
    		return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++);
    	}
    	template<class T>
    	inline void read(T &x){
    		static bool iosig;
    		static char c;
    		for(iosig=false,c=read();!isdigit(c);c=read()){
    			if(c=='-')iosig=true;
    			if(c==-1)return;
    		}
    		for(x=0;isdigit(c);c=read())x=((x+(x<<2))<<1)+(c^'0');
    		if(iosig)x=-x;
    	}
    	inline char readc(char &c){
    		for(c=read();!isalpha(c)&&!isdigit(c);c=read())
    		if(c==-1)return 0;
    	}
    	const int OUT_LEN = 10000000;
    	char obuf[OUT_LEN],*ooh=obuf;
    	inline void print(char c) {
    		if(ooh==obuf+OUT_LEN)fwrite(obuf,1,OUT_LEN,stdout),ooh=obuf;
    		*ooh++=c;
    	}
    	template<class T>
    	inline void print(T x){
    		static int buf[30],cnt;
    		if(x==0)print('0');
    		else{
    			if(x<0)print('-'),x=-x;
    			for(cnt=0;x;x/=10)buf[++cnt]=x%10+48;
    			while(cnt)print((char)buf[cnt--]);
    		}
    	}
    	inline void flush(){fwrite(obuf,1,ooh-obuf,stdout);}
    }
    namespace fastIO2{
    	template<class T>
    	inline void read(T &x){
    		static bool iosig;
    		static char c;
    		for(iosig=false,c=getchar();!isdigit(c);c=getchar()){
    			if(c=='-')iosig=true;
    			if(c==-1)return;
    		}
    		for(x=0;isdigit(c);c=getchar())x=((x+(x<<2))<<1)+(c^'0');
    		if(iosig)x=-x;
    	}
    }
    using namespace fastIO1;
    const int inv2=(P+1)>>1,inv4=(P+1)>>2;
    int n,m,cnt;struct node{LL S;int p;}a[233333];
    map<int,int>f[1<<16];
    LL calc(int x,int y){return (1ll<<x-1)+(1ll<<(y+n-1));}
    int dp(LL S){
    	if(!S)return 1;
    	int L=S>>n,R=S^(L<<n);
    	if(f[L].count(R))return f[L][R];
    	int ans=0;
    	for(int i=1;i<=cnt;i++){
    		LL T=a[i].S;
    		if((T&S)==T&&(T<<1)>S)
    		(ans+=1ll*dp(S^T)*a[i].p%P)%=P;
    	}
    	return f[L][R]=ans;
    }
    int main(){
    	read(n),read(m);
    	for(int i=1;i<=m;i++){
    		int tp,x,y;LL S;
    		read(tp),read(x),read(y),S=calc(x,y);
    		a[++cnt]=(node){S,inv2};
    		if(tp){
    			int x1,y1,S1; read(x1),read(y1),S1=calc(x1,y1);
    			a[++cnt]=(node){S1,inv2};if(S&S1)continue;
    			a[++cnt]=(node){S|S1,(tp==2?-1:1)*inv4};
    		}
    	}
    	printf("%lld
    ",(1ll*(1ll<<n)*dp((1ll<<(2*n))-1)%P+P)%P);
    }
    
  • 相关阅读:
    js代码点击触发事件
    鼠标经过事件(onmouseover)
    Python使用win32com实现的模拟浏览器功能
    python 操作剪切板
    python 比较两个yaml文件
    Python:ModuleNotFoundError: No module named 'windows'
    ModuleNotFoundError: No module named 'pymouse'
    Javascript中点击(click)事件的3种写法
    如何调整 php 应用的上传附件大小?
    如何用 iptables 禁止某个ip?
  • 原文地址:https://www.cnblogs.com/Romeolong/p/10288105.html
Copyright © 2011-2022 走看看