zoukankan      html  css  js  c++  java
  • 洛谷 P3175 [HAOI2015]按位或

    题目分析

    与hdu4336 Card Collector相似,使用min-max容斥。

    (max(S))表示集合(S)中最后一位出现的期望时间。

    (min(S))表示集合(S)中最初一位出现的期望时间。

    由min-max容斥可得:

    (max(T)=sumlimits_{S subseteq T}(-1)^{|T|-1}min(S))

    考虑求每一个(min(S))

    一个很显然的暴力代码:

    	for(int i=0;i<(1<<n);i++){
    		double tot=0;
    		for(int j=0;j<(1<<n);j++)if(i&j)tot+=p[j];
    		Min[i]=tot; 
    	}
    

    我们考虑对于每一个集合(S),实质上只有与它没有交集的数对它没有贡献。

    那么我们可以用总贡献减去与它没有交集的数的贡献。

    即对于每一个数,只需要对它的补集的子集全部减去它的贡献即可。

    这个很显然能够(O(nlogn))计算出来。

    那么就做完啦。

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    double p[(1<<20)+5],a[25];
    int main(){
    	scanf("%d",&n);
    	for(int i=0;i<(1<<n);i++){
    		double x;
    		scanf("%lf",&x);
    		p[((1<<n)-1)^i]+=x;
    		for(int j=0;j<n;j++)
    			if(i&(1<<j))a[j]+=x;
    	}
    	for(int i=0;i<n;i++)if(!a[i]){puts("INF");return 0;}
    	for(int j=0;j<n;j++)
    		for(int i=0;i<(1<<n);i++)
    			if(i&(1<<j))p[i^(1<<j)]+=p[i];
    	for(int i=0;i<(1<<n);i++)p[i]=1-p[i];
    	double ans=0;
    	for(int i=1;i<(1<<n);i++){
    		int f=(__builtin_popcount(i)&1)?1:-1;
    		ans+=f/p[i];
    	}
    	cout<<fixed<<setprecision(7)<<ans<<"
    ";
    }
    
  • 相关阅读:
    Get code into Bitbucket fast using Atlassian's SourceTree or the command line
    Django+angularJs
    修改默认python版本
    重拾python mac1.9.2
    REST
    Parameters.Add Parameters.Addrange
    sql建表前删除存在的同名表
    C#1.0
    [转]C#究竟能给开发者带来什么
    Laravel中上传图片至七牛云
  • 原文地址:https://www.cnblogs.com/Trrui/p/9990032.html
Copyright © 2011-2022 走看看