hdu3929
二项式定理有两个性质,第一个是高中就接触过的,即奇数项(这里的奇数项与题目的奇数项定义不同)和偶数项系数之和相同
第二个也可以记住
阶乘分解质因数注意复习一下
这里拓展一个:
证明:设
当然这也告诉我们:中途一旦产生进位了,那么
为什么?我们从竖式加法的角度考虑。从低位往高位进行加法,第一次进行的时候一定是两个
为什么这里是覆盖奇数次?因为偶数不改变奇偶性
这个典型的容斥原理简单来说,就是先求每个
先求每个
再减掉每两个
再加上三个
很显然就是被覆盖了奇数次的集合
由于这道题目只用统计个数,我们没有必要每次去算出具体的集合,而是可以直接累加贡献,所以时间复杂度为
代码可以看看这篇文章
这篇文章的代码:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<vector>
#define ll __int64
#define pi acos(-1.0)
#define MAX 50000
using namespace std;
ll an[16],ans;
int n;
int get(ll n)
{
int t=0;
while(n){
n-=(n&-n);
t++;
}
return t;
}
void dfs(int i,ll sum,ll k)//递归版容斥原理
{
ans+=(1ll<<(get(sum)))*k;
for(int j=i+1;j<n;j++)
dfs(j,sum&an[j],-2*k);
}
ll solve(int n)//迭代版容斥原理
{
ll ans=0,res,m=1;
int i,j,temp;
for(i=1;i<(1<<n);i++){
temp=0;
for(j=0;j<n;j++){
if(i&(1<<j)){
temp++;
if(temp==1) res = an[j];
else res=res&an[j];
}
}
res=(1<<get(res));
ans+=m*res;
m*=-2;
}
return ans;
}
int main(){
int i,t,k=1;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%I64d",&an[i]);
ans=0;
for(i=0;i<n;i++)
dfs(i,an[i],1);
printf("Case #%d: %I64d\n",k++,ans);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!