【SDOI2013]スプリングス(検索+ハッシュ+および除外)

問題の意味

所与\(N- \)時間、毎回6つの重み、正確に見つける\(K \)時間の対数に対応する重みの数に等しいです

考え

重みが等しい列挙することができ、同一の重みの数が少ない、再びハッシュするたびに、対応する加重値に、あなたはどのくらいの時間これらの重みを得ることができます

しかし、明らかにこの計算には、例えば、4点の重み同時にそれが、その後反発を受け始めることができる3つの重みと同じになりますが繰り返されます

セット\(F_iと\)は、少なくともことを示している\(Iは\)時間の対数に対応する重み値に等しく、すなわち、列対上に求めて、提供\(G_i \)は、正確に表す\(Iは\)重み番目等しい時間の対応する数、すなわち解答

はず(f_i- G_i = \ {G_Jシグマ}、(私はJ \のLeqを<6)\)\、実際の中\(F_iと\)以上が存在することになる\(G_J \)のような、\(J = 5、I = 3 \) \(F_3 \)があろう(g_5 \)\一緒に、それが追加される必要に応じて三つの値\(C(5,3)を\)

上から見た、\(G \)式がなければならない\(g_i = f_i- \シグマ{ g_j * C(J、I)}(iはj個の\当量6 <)\)

コード

#include<bits/stdc++.h>
#define N 1000005
#define re register
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ull base = 1000000007;
int n,k,a[N][7],st[7],top;
ll f[8],g[8],C[10][10];
ull has[N];

template <class T>
void read(T &x)
{
    char c;int sign=1;
    while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    while((c=getchar())>='0'&&c<='9') x=x*10+c-48; x*=sign;
}

void deal()
{
    for(re int i=1;i<=n;++i)
    {
        has[i]=0;
        for(re int j=1;j<=top;++j) has[i]=has[i]*base+a[i][st[j]]+1;
    }
    sort(has+1,has+n+1);
    ll len=0;
    for(re int i=1;i<=n;++i)
    {
        if(has[i]!=has[i-1])
        {
            f[top]+=(len-1)*len/2;
            len=1;
        }
        else ++len;
    }
    f[top]+=(len-1)*len/2;
}
int main()
{
    C[1][0]=C[1][1]=1;
    for(re int i=2;i<10;++i)
    {
        C[i][0]=1;
        for(re int j=1;j<=i;++j)
        C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
    read(n);read(k);
    for(re int i=1;i<=n;++i)
      for(re int j=1;j<=6;++j)
        read(a[i][j]);
    for(re int i=0;i<64;++i)
    {
        top=0;
        for(re int j=0;j<6;++j) if(i>>j&1) st[++top]=j+1;
        deal();
    }
    for(re int i=6;i>=k;--i)
    {
        g[i]=f[i];
        for(re int j=i+1;j<=6;++j)
        g[i]-=g[j]*C[j][i];
    }
    cout<<g[k]<<endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/Chtholly/p/11628189.html