现在的位置: 首页 > 综合 > 正文

hdu 4901

2018年02月23日 ⁄ 综合 ⁄ 共 1264字 ⁄ 字号 评论关闭

思路:各种状态转移统计一下,然后乘啊乘。G++T了,C++过了。

这里解释下吧:

a[i][j]代表前i个中包括第i个且异或值为j的集合的个数

b[i][j]代表前i个所有的异或值为j的集合的个数(与a不同,这里包含了包括第i个和不包括第i的情况)

c[i][j]代表第i个到最后一个中,包括第i个且 与运算的值为j的集合个数(这里的确用不着)

d[i][j]代表第i个到最后一个中,所有与运算为j的集合个数(可包括i,也可不包括i)

我这里用的是a与d运算求结果,其实也可用b与c来算。至于为什么乘啊乘应该不难理解吧,不理解自己想吧。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const long long M=1e9+7;
long long a[1111][1111],b[1111][1111],c[1111][1111],d[1111][1111];
int n,aa[1111];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&aa[i]);
        if(n==1||n==0)
        {
            printf("0\n");
            continue;
        }
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        memset(d,0,sizeof(d));
        a[1][aa[1]]=1;
        b[1][aa[1]]=1;
        for(int i=2;i<=n;i++)
        {
            a[i][aa[i]]+=1;
            b[i][aa[i]]+=1;
            for(int j=0;j<1024;j++)
            {
                if(b[i-1][j])
                {
                    a[i][j^aa[i]]+=b[i-1][j];
                    b[i][j^aa[i]]+=b[i-1][j];
                    b[i][j]+=b[i-1][j];
                    a[i][j^aa[i]]%=M;
                    b[i][j^aa[i]]%=M;
                    b[i][j]%=M;
                }
            }
        }
        c[n][aa[n]]=1;
        d[n][aa[n]]=1;
        for(int i=n-1;i>=1;i--)
        {
            c[i][aa[i]]+=1;
            d[i][aa[i]]+=1;
            for(int j=0;j<1024;j++)
            {
                if(d[i+1][j])
                {
                    c[i][j&aa[i]]+=d[i+1][j];
                    d[i][j&aa[i]]+=d[i+1][j];
                    d[i][j]+=d[i+1][j];
                    c[i][j&aa[i]]%=M;
                    d[i][j&aa[i]]%=M;
                    d[i][j]%=M;
                }
            }
        }
        long long ans=0;
        for(int i=1;i<n;i++)
        {
            for(int j=0;j<1024;j++)
            {
                if(a[i][j]&&d[i+1][j])
                {
                    ans+=a[i][j]*d[i+1][j];
                    ans%=M;
                }
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

抱歉!评论已关闭.