[TC14126]BagAndCards

[TC14126]BagAndCards

题目大意:

\(n(n\le500)\)个袋子,第\(i\)个袋子里有\(count[i][j]\)张值为\(j(j\le m\le500)\)的牌。给一个长度为\(2m-1\)的序列,告诉你\(0~2m-1\),哪些数是好数。求对于每一对袋子\((i,j)\),从\(i\)拿一张牌,再从\(j\)拿一张牌,两张牌之和为一个好数的方案数。

思路:

预处理\(sum[i][j]\)表示\(j\)能和\(i\)中的多少数组成好数,然后就可以直接求了。

时间复杂度\(\mathcal O(n^2m+nm^2)\)

源代码:

#include<string>
class BagAndCards {
    private:
        using int64=long long;
        static constexpr int N=500,mod=1e9+7;
        int count[N][N],sum[N][N];
    public:
        int getHash(const int &n,const int &m,int x,const int &a,const int &b,const int &c,const std::string &isGood) {
            for(register int i=0;i<n;i++) {
                for(register int j=0;j<m;j++) {
                    count[i][j]=x;
                    x=(((int64)x*a+b)^c)%mod;
                }
            }
            for(register int i=0;i<n;i++) {
                for(register int j=0;j<m;j++) {
                    for(register int k=0;k<m;k++) {
                        if(isGood[j+k]=='Y') {
                            (sum[i][j]+=count[i][k])%=mod;
                        }
                    }
                }
            }
            int ans=0;
            for(register int i=0;i<n;i++) {
                for(register int j=i+1;j<n;j++) {
                    int tmp=0;
                    for(register int k=0;k<m;k++) {
                        (tmp+=(int64)count[i][k]*sum[j][k]%mod)%=mod;
                    }
                    ans^=tmp;
                }
            }
            return ans;
        }
};

猜你喜欢

转载自www.cnblogs.com/skylee03/p/9711528.html
tc