Description
济南,中国环渤海地区南翼和黄河中下游地区中心城市,山东省省会,山东省第一大城市,山东省政治、文化、教育中心,华东五大城市之一,区域性金融中心,副省级城市。济南位于山东省中西部,北临黄河,南依泰山。济南分别与西南部的聊城、北部的德州和滨州、东部的淄博、南部的莱芜和泰安交界。济南有着2700 余年的历史,是龙山文化的发祥地。因境内有“七十二名泉”故被称为“泉城”,并素有“四面荷花三面柳,一城山色半城湖”
的美誉。济南历史上涌现了很多文人墨客,著名有李清照、辛弃疾等。济南是国家创新型城市、中国软件名城、全国重要的交通枢纽和物流中心。继济南全运会取得圆满成功后,2013年济南将举办第十届中国艺术节,并成为2015 年“第二十二届国际历史科学大会”的主办城市,为济南建设国际大都市注入了新的活力。
济南市“泉历史研究小组”依据济南特有的泉脉关系将济南的泉水分为六个区域,分别是市中区、历下区、天桥区、槐荫区、历城区、长清区。
作为光荣的济南泉历史研究小组中的一员,铭铭收集了历史上N 个不同年份时不同泉区的泉水流量指数,这个指数是一个小于2^30 的非负整数。第i 个年份时六个泉区的泉水流量指数分别为A(i,1),A(i,2),A(i,3),A(i,4),A(i,5)与A(i,6)。
现在铭铭希望知道有多少对不同的年份:i 和j,满足这两年恰好有K 个泉区的泉水流量指数对应相同。
的美誉。济南历史上涌现了很多文人墨客,著名有李清照、辛弃疾等。济南是国家创新型城市、中国软件名城、全国重要的交通枢纽和物流中心。继济南全运会取得圆满成功后,2013年济南将举办第十届中国艺术节,并成为2015 年“第二十二届国际历史科学大会”的主办城市,为济南建设国际大都市注入了新的活力。
济南市“泉历史研究小组”依据济南特有的泉脉关系将济南的泉水分为六个区域,分别是市中区、历下区、天桥区、槐荫区、历城区、长清区。
作为光荣的济南泉历史研究小组中的一员,铭铭收集了历史上N 个不同年份时不同泉区的泉水流量指数,这个指数是一个小于2^30 的非负整数。第i 个年份时六个泉区的泉水流量指数分别为A(i,1),A(i,2),A(i,3),A(i,4),A(i,5)与A(i,6)。
现在铭铭希望知道有多少对不同的年份:i 和j,满足这两年恰好有K 个泉区的泉水流量指数对应相同。
Input
第一行有2 个整数,分别是N 个K。
之后N 行,每行有6 个整数。第i 行的第j 个数字(i,j)表示第i 个年份中第j 个泉区的泉水流量指数。
之后N 行,每行有6 个整数。第i 行的第j 个数字(i,j)表示第i 个年份中第j 个泉区的泉水流量指数。
Output
只一行,一个整数。表示有多少对不同的年份,满足恰有K 个泉区的泉水流量指数对应相同。
Sample Input
3 3
1 2 3 4 5 6
1 2 3 0 0 0
0 0 0 4 5 6
Sample Output
2
Data Constraint
有8%的数据,N<=1000,A<=20
有8%的数据,N<=1000,A<=2^30
有24%的数据,N<=100000,A<=20
有28%的数据,N<=10000,A<=2^30
有32%的数据,N<=100000,A<=2^30
对于100%的数据,0<=K<=6,且所有数据中K 是等概率出现的,即对于任意的0<=x<=6,都有大约1/7 的数据中K=x。
有8%的数据,N<=1000,A<=2^30
有24%的数据,N<=100000,A<=20
有28%的数据,N<=10000,A<=2^30
有32%的数据,N<=100000,A<=2^30
对于100%的数据,0<=K<=6,且所有数据中K 是等概率出现的,即对于任意的0<=x<=6,都有大约1/7 的数据中K=x。
分析
题意为在n个六元组中求出有多少对满足刚好k个对应位置的量相等
k很小,我们可以枚举所有2^6种状况
我们发现刚好有k种的情况比较难做,不如考虑至少k种的
设至少k种的情况为f[k]
那么ans=f[k]-f[k+1]*C(k+1,k)+f[k+2]*C(k+2,k)-f[k+3]*C(k+3,k)+……
k+x<=6
为什么要乘上C(k+x,k)呢?我们可以发现每个刚好为k+x的情况都可以对答案产生C(k+x,k)的贡献
#include <iostream> #include <cstdio> #include <memory.h> using namespace std; typedef unsigned long long ull; typedef long long ll; const int N=1e5+10; const int P=17453343; const int Typi=133345; struct List { ull v; int nx,cnt; }l[N]; int cnt,list[P]; int n,k; int a[N][7]; ll ans,C[7][7]; void Insert(ull x) { int u=x%P; for (int i=list[u];i;i=l[i].nx) if (l[i].v==x) { l[i].cnt++; return; } l[++cnt]=(List){x,list[u],1};list[u]=cnt; } void Calc(int m) { int rnt=0; for (int i=0;i<6;i++) if (m&(1<<i)) rnt++; if (rnt<k) return; memset(list,0,sizeof list);cnt=0; for (int i=1;i<=n;i++) { ull hash=0; for (int j=0;j<6;j++) if (m&(1<<j)) hash=hash*Typi+a[i][j]; Insert(hash); } ll count=0; for (int i=1;i<=cnt;i++) count+=1ll*l[i].cnt*(l[i].cnt-1)/2; count*=C[rnt][k]; ans+=((rnt-k)%2?-1:1)*count; } int main() { C[0][0]=1; for (int i=1;i<=6;i++) { C[i][0]=1; for (int j=1;j<=i;j++) C[i][j]=C[i-1][j-1]+C[i-1][j]; } scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) for (int j=0;j<6;j++) scanf("%d",&a[i][j]); for (int i=0;i<(1<<6);i++) Calc(i); printf("%lld",ans); }