列表

详情


NC20576. [SDOI2013]SPRING

描述

输入描述

输出描述

示例1

输入:

3 3 
1 2 3 4 5 6
1 2 3 0 0 0
0 0 0 4 5 6

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 864ms, 内存消耗: 44000K, 提交时间: 2019-09-26 20:30:50

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int N=100010,mod1=233,mod2=1e7+33;
int n,m,cnt,a[N][7],c[7][7],head[mod2+10],to[N],nxt[N];
ll ans,sm[N];
inline int read()
{
    int x=0;
    char c=getchar();
    bool flag=0;
    while(c<'0'||c>'9') {if(c=='-')flag=1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x+(x<<2)<<1)+ c-'0';c=getchar();}
    return flag?-x:x;
}
inline bool check(int x,int y,int k)
{
    for(int i=1;i<=6;++i) if (k&(1<<(i-1)) && a[x][i]!=a[y][i]) return 0;
    return 1;
}
inline ll calc(int k)
{
    ll res=0,cnt=0,p;
    memset(head,0,sizeof(head));
    for(int i=1;i<=n;++i)
    {
        ll x=0;
        for(int j=1;j<=6;++j) if (k&(1<<(j-1))) x=(x*mod1+a[i][j])%mod2;
        for (p=head[x];p;p=nxt[p]) if(check(to[p],i,k)) {res+=sm[p]++;break;}
        if (!p) to[++cnt]=i,sm[cnt]=1,nxt[cnt]=head[x],head[x]=cnt;
    }
    return res;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;++i) for(int j=1;j<=6;++j) a[i][j]=read();
    c[0][0]=1; for(int i=1;i<=6;++i){c[i][0]=1;for(int j=1;j<=6;++j) c[i][j]=c[i-1][j-1]+c[i-1][j]; }
    for(int S=0;S<=63;++S)
    {
        int cnt=0;
        for(int i=0;i<=5;++i) if(S&(1<<i)) cnt++;
        if(cnt<m) continue;
        ll t=calc(S)*c[cnt][m];
        ans+=(cnt-m)&1?-t:t;
    }
    printf("%lld\n",ans);
}

上一题