HDU 5119 Happy Matt Friends

来源:互联网 发布:婚礼入场音乐知乎 编辑:程序博客网 时间:2024/05/01 13:14

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5119


题意:N个人,每个人有一个值,现在求选取一些人(可以是0个)使得他们异或之后的结果不小于m的方案数。


思路:f[i][j]表示前i个人的异或值为j的方案数。

那么对于当前第i个人,可以选他也可以不选他。所以f[i][j] = f[i-1][j] + f[i-1][j^a[i]] a[i]<=10^6,注意a[i]^j的范围,最后计算∑f[n][i]  i>=M。内存有限,所以用滚动数组。


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod %100000007const int maxn = 1050000;LL f[2][maxn+100];int x[50];int T,n,m;void init(){    Clean(f,0);    f[0][0] = 1;    rep(i,1,n)    {        scanf("%d",&x[i]);    }}LL solve(){    int cur,next;    cur = 0 , next = 1;    rep(i,1,n)    {        Clean(f[next],0);        rep(j,0,maxn)        {            f[next][j] = f[cur][j];            if (  ( j ^ x[i] ) < maxn ) f[next][j] += f[cur][ j ^ x[i] ];        }        cur = 1 - cur , next = 1 - next;    }    LL s = 0;    rep(i,m,maxn) s+=f[cur][i];    return s;}int main(){    cin>>T;    rep(kase,1,T)    {        scanf("%d%d",&n,&m);        init();        printf("Case #%d: %I64d\n",kase,solve());    }    return 0;}



0 0