.jpg)
【原题】
.jpg)
.jpg)


【题解】这道题明明是水题,坑了我两天!!!真是伤心。发现哈希都不熟练了。
首先很容易想到是2^6枚举01状态,使得1的个数不小于K。比如枚举了0110000,我们就可以用一个哈希来处理个数。然后统计一下结果即可。开始的代码如下:
【代码1】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
using namespace std;
int n,k,num,i,j,p,x[N][6],status,Time,flag;
typedef long long ll;ll ans,h1,h2;
const ll hash1=999997;
const ll hash2=233333;
int f1[hash1],f2[hash2];
int main()
{
scanf("%d%d",&n,&k);num=1<<6;
for (i=1;i<=n;i++)
for (j=0;j<6;j++)
scanf("%d",&x[i][j]);
for (status=0;status<num;status++)
{
flag=0;
for (j=0;j<6;j++)
flag+=(status&(1<<j))?1:0;
if (flag<k) continue;
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
for (i=1;i<=n;i++)
{
h1=1;h2=1;
for (j=0;j<6;j++)
if (status&(1<<j))
{
h1=(h1+ll(1<<j)*ll(x[i][j]))%hash1;
h2=(h2+ll(1<<j)*ll(x[i][j]))%hash2;
}
Time=min(f1[h1],f2[h2]);
ans+=(long long)Time;
f1[h1]++;f2[h2]++;
}
}
printf("%lld",ans);
return 0;
} 【代码2】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
using namespace std;
int n,k,num,i,j,p,x[N][6],C[7][7],status,Time,flag,del;
typedef long long ll;ll ans,h1,h2;
const ll hash1=999997;const ll base1=97;
const ll hash2=233333;const ll base2=23;
int f1[hash1],f2[hash2];
int main()
{
scanf("%d%d",&n,&k);
for (i=1;i<=n;i++)
for (j=0;j<6;j++)
scanf("%d",&x[i][j]);
C[0][0]=1;
for (i=1;i<=6;i++)
{
C[i][0]=1;
for (j=1;j<=i;j++) C[i][j]=C[i-1][j]+C[i-1][j-1];
}
for (status=0;status<64;status++)
{
flag=0;if (status==52)
status=52;
for (j=0;j<6;j++)
flag+=(status&(1<<j))?1:0;
if (flag<k) continue;
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
Time=0;
for (i=1;i<=n;i++)
{
h1=0ll;h2=0ll;
for (j=0;j<6;j++)
if (status&(1<<j))
{
h1=(h1*base1+ll(x[i][j]))%hash1;
h2=(h2*base2+ll(x[i][j]))%hash2;
}
Time+=min(f1[h1],f2[h2]);
f1[h1]++;f2[h2]++;
}
del=((flag-k)&1)?-1:1;
ans+=(long long)Time*del*C[flag][k];
}
printf("%lld",ans);
return 0;
} 【AC代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
using namespace std;
int n,k,num,i,j,p,x[N][6],C[7][7],status,flag,pre,cnt,t;
typedef long long ll;ll ans,h,Time,del;
const ll hash=99997;const ll base=97;
struct arr{int num,s,next;}a[100005];
int end[hash],temp[7],f[100005][7],data[100005];
ll doit(int k)
{
int j;
for (int i=end[k];i;i=a[i].next)
{
j=0;
if (a[i].num==t)
for (j=1;j<=t;j++)
if (temp[j]!=f[i][j]) break;
if (j==t+1) return ++a[i].s;
}
if (!end[k]) data[++pre]=k;
cnt++;a[cnt].num=t;a[cnt].s=0;a[cnt].next=end[k];end[k]=cnt;
for (j=1;j<=t;j++) f[cnt][j]=temp[j];return 0;
}
inline int Read()
{
int x=0;char ch=getchar();bool positive=1;
for (;ch<‘0‘||ch>‘9‘;ch=getchar()) if (ch==‘-‘) positive=0;
for (;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘;
return positive?x:-x;
}
int main()
{
scanf("%d%d",&n,&k);
for (i=1;i<=n;i++)
for (j=0;j<6;j++)
x[i][j]=Read();
C[0][0]=1;
for (i=1;i<=6;i++)
{
C[i][0]=1;
for (j=1;j<=i;j++) C[i][j]=C[i-1][j]+C[i-1][j-1];
}
for (status=0;status<64;status++)
{
flag=0;pre=0;
for (j=0;j<6;j++)
flag+=(status&(1<<j))?1:0;
if (flag<k) continue;
Time=0ll;
for (i=1;i<=n;i++)
{
h=0ll;t=0;
for (j=0;j<6;j++)
if (status&(1<<j))
h=(h*base+ll(x[i][j]))%hash,temp[++t]=x[i][j];
Time+=doit(h);
}
cnt=0;for (i=1;i<=pre;i++) end[data[i]]=0;
del=((flag-k)&1)?-1ll:1ll;
ans+=(ll)(Time*del*C[flag][k]);
}
printf("%lld",ans);
return 0;
}
.jpg)
.jpg)


Dragonite修正数据
Hash
bzoj 3198: [Sdoi2013]spring 题解,布布扣,bubuko.com
bzoj 3198: [Sdoi2013]spring 题解
原文地址:http://blog.csdn.net/jiangshibiao/article/details/26286131