题意
给个年份,每个年份有个水流指数到。
问有多少对年份满足恰好有个水流指数相同。
思路
容斥+二项式反演
转为钦定个相同,其余随便放(也就至少的意思)
枚举相同的集合,我本来是把对应位取出来排序的,但太慢了。
哈希挂链法是个好东西,跑得又快,接近,而且没有冲突。
code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5,bs=233,mod=1e7+33;
const int M=mod+5;
typedef long long ll;
int n,k,a[N][7],b[N][7],ecnt,head[M],to[N],nxt[N],cnt[N];
ll C[7][7];
bool check(int s,int x,int y) { //位数s下x和y是否相同
for(int i=0;i<6;i++) {
if(s&(1<<i)) {
if(a[x][i]!=a[y][i])return 0;
}
}
return 1;
}
int st[N],tp;
void solve() {
ll ans=0;
for(int s=0,up=1<<6;s<up;s++) {
int ppc=0;
for(int i=0;i<6;i++) {if((1<<i)&s) ppc++;}
if(ppc<k) continue;
ll res=0;
for(int i=1;i<=n;i++) {
ll x=0;
for(int j=0;j<6;j++) {if((1<<j)&s){x=(x*bs+a[i][j])%mod;}}
int j=head[x];
for(;j;j=nxt[j]) {
if(check(s,to[j],i)) {res+=cnt[j]++;break;}
}
if(!j){nxt[++ecnt]=head[x];to[ecnt]=i;cnt[ecnt]=1;head[x]=ecnt;st[++tp]=x;}
}
res*=C[ppc][k];
ans+=(ppc-k)&1?-res:res;
ecnt=0;for(int i=1;i<=tp;i++)head[st[i]]=0;tp=0;
}
printf("%lld",ans);
}
int main() {
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)for(int j=0;j<6;j++)scanf("%d",&a[i][j]);
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];
}
solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2021-07-14 总结
2021-07-14 goose消元