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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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
    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
    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
    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];
mapf[1<<16];
LL calc(int x,int y){return (1ll<>n,R=S^(L<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\n",(1ll*(1ll<

转载于:https://www.cnblogs.com/Romeolong/p/10288105.html

你可能感兴趣的:(THUWC2017 随机二分图)