孤独

【题目描述】 小 X 是一个孤独的 OIer,退役后他发现他无法和其他人找到共同的话题。 好在小 X 有 M 名同学,小 X 希望通过 K 天的交流拉近与他们的关系。 这 M 名同学可能感兴趣的话题共有 N 种,我们用一个 N 位的二进制数 Ai 来 表示一位同学对于各个话题是否感兴趣,例如,当 N=3,Ai=二进制数 110(即 十进制数 6),表示第 i 位同学对第 1、第 2 个话题感兴趣,而对第 3 个话题不感 兴趣。 每天,小 X 会选择一位同学,与其交流一个他感兴趣的话题。由于 OIer 的 记忆只有 7 秒,所以小 X 每天与同学交流的话题必须都一样。 现在,小 X 想要知道他有多少种不同的方式选择每天交流的同学,使得他能 够找到至少一个话题,顺利地完成和他们的交流。两种选取方案不同,当且仅当 在某一天小 X 选择的同学不同。 由于答案可能很大,输出其对 10 9+7 取模的结果。 【输入格式】 从文件 loneliness.in 中读取数据。 第一行一个整数 Num,表示测试点编号,以便选手方便地获得部分分,你可 能不需要用到这则信息,样例中 Num 的含义为数据范围与某个测试点相同。 接下来一行三个整数 N、M、K,含义见题面描述。 接下来一行 M 个整数 Ai,表示每名同学可能感兴趣的话题,以十进制的方 式给出。 【输出格式】 一行一个整数,表示方案数对 10 9+7 取模的结果。 【样例 1 输入】 2 2 3 4 1 2 3 【样例 1 输出】 31 【样例 1 解释】 在这个样例中,我们只需要不同时选取 1 号和 2 号同学就能够保证小 X 能够 找到合适的话题。 因此方案数为(不选 1 号的方案数+不选 2 号的方案数-不选 1 号且不选 2 号 的方案数)=16+16-1=31。

 

根据容斥原理,答案就应该是每个话题的方案数,减去两个话题的方案数,加上三个话题的方案数,再减去四个话题的方案数,… 
分析一下复杂度,计算枚举话题的方案数乘上每次统计当前这种话题的方案数O(2n∗m2n∗m) 
这个会时间超限,关键就是在统计方案数。 
一个数,如果对某个方案贡献,就是这个数是它的子集, 
考虑一种更加优秀的枚举子集办法。
 

#include
#define f(i,l,r) for(i=(l);i<=(r);i++)
using namespace std;
const int MAXN=100005,MOD=1e9+7;
int num,n,m;
long long K;
int sta[MAXN];
long long opt[1<<25];
long long ans;
long long Pow(long long a,long long num)
{
	long long res=1;
	for(;num;num>>=1){
		if(num&1) res=(res*a)%MOD;
		a=(a*a)%MOD;
	}
	return res;
}
bool cal(int x)
{
	int res=0;
	while(x){
		res++;
		x-=(x&(-x));
	}
	if(res&1) return true;
	return false;
}
int main()
{
	ios::sync_with_stdio(false);
	int i,j;
	cin>>num;
	cin>>n>>m>>K;
	f(i,1,m){
		cin>>sta[i];
		for(j=sta[i];j;j=(j-1)&(sta[i])){
			opt[j]++;
		}
	}
	f(i,1,(1<
#include
#include
#include
#define N 2000000
#define mo 1000000007
#define LL long long
using namespace std;

LL ans;
int n,m,k,x,s[N],hjy[N];
LL mul(LL x,LL y){
    if (y==1) return x;
    LL o=mul(x,y/2);
    o=(o*o)%mo;
    if (y%2==1) o=(o*x)%mo;
    return o;
}

inline void dfs(int x,int dep){
    if (dep==n) {
        int o=x,p=0;
        while (o){
            if (o%2==1) p++;
            o>>=1; 
        }
        if (p==0) return; 
        if (p%2==0) ans=(ans-mul(s[x],k)+mo)%mo;
            else ans=(ans+mul(s[x],k))%mo;
        return;
    }
    dfs((x<<1)+1,dep+1);
    dfs(x<<1,dep+1);
}

int main(){
    freopen("a.in","r",stdin);
//  freopen("loneliness.in","r",stdin);
//  freopen("loneliness.out","w",stdout);
    scanf("%d",&x);
    scanf("%d%d%d",&n,&m,&k);
    for (int i=1;i<=m;i++) {
        scanf("%d",&x);
        s[x]++;
    }
    for (int i=0;i
#include
#define mo 1000000007
#define ll long long
using namespace std;
ll m,n,k,f[1100010],g[1100010],x,ans;
ll po(ll x,ll y){ll z=1;while (y){if (y%2==1)z=(x*z)%mo;x=(x*x)%mo;y/=2;}return z;}
int main(){
	//freopen("loneliness.in","r",stdin);
	//freopen("loneliness.out","w",stdout);
	cin>>n;
	cin>>n>>m>>k;
	for (int i=1;i<=m;i++){scanf("%d",&x);g[x]++;}
	f[0]=-1;
	for (int i=0;i<(1<

 

你可能感兴趣的:(数学)