Even Numbers (找规律or组合数+规律) Gym - 101972J

题目链接:https://vjudge.net/problem/Gym-101972J

                                                   Gym - 101972J

Yousef loves playing with functions in his free time. Today, he invents the following function:

Yousef will give you a list of queries, and you need to find the answers for them. For each query, you are given an integer n, and your task is to count the number of integers m in which (0 ≤ m ≤ n) and calc(n,  m) is an even number. Can you?

Input

The first line contains an integer T (1 ≤ T ≤ 105) specifying the number of test cases.

Each test case consists of a single line containing an integer n (0 ≤ n ≤ 1018), as described in the problem statement above.

Output

For each test case, print a single line containing the number of integers m in which (0 ≤ m ≤ n) and calc(n,  m) is an even number.

Example

Input

2
1
2

Output

0
1

 

题目大意:给你一个n,要你求出有多少个m(0<=m<=n)使得calc(n,m)为偶数 

思路:我做的时候先是根据题目给的公式进行推,到最后啥也没推出来。

之后写了一个代码进行打表找规律。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
typedef long long ll;
int dfs(int n,int m)
{
	if(m<=-1||m>n)return 0;
	if(n==0&&m==0)return 1;
	return dfs(n-1,m-1)+dfs(n-1,m);
}

int main()
{
	int n,m;
	while(cin>>n){
		int i,j;
		int num=0,sum;
		for(i=0;i<=n;i++)
		{
			sum=dfs(n,i);
			if(sum%2==0)num++;
		}
		printf("%d  偶数:%d 奇数:%d\n",n,num,n+1-num);
	}
	return 0;
}

 

可以发现数的二进制中1的数目和使得结果为奇数的数目有关。

a为1的数目,则1<<a 即2^a 为奇数的数目。

做这个题时当时傻了,弄不清 1<<a 和 a<<1(即a*2) 的区别了

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
typedef long long ll;
int T;
ll n,m,cnt;
int main(){
	
	scanf("%d",&T);
	while(T--){
		scanf("%lld",&n);
		m=n;
		cnt=0; 
		while(m)      
		{   
		    if(m&1)cnt++; 
		    m=m>>1;
		}
		cnt=(1LL)<<cnt;
		printf("%lld\n",n+1-cnt);
	}
	return 0; 
}

 

网上的题解说的是组合数。在这里摘录一下。

 最开始第一反应就是打表,我输入n,把m=0~n全部枚举一遍,计算对应的calc(n,m)的值,后来发现这是一个组合数公式,满足:C_{n}^{m}\textrm{}=calc(n,m) ,那么这就好办了,对于n,我们只需要在0~n范围内有多少个数满足C_{n}^{m}\textrm{} 是偶数了,然后百度发现当 n & m == m时C_{n}^{m}\textrm{} 为奇数,那么将n转换为二进制后,n&m==m与的条件是当n的某一位为1时,m是可以取任意的(0或1),当n的位置为0时,那么m对应位置只能为0才行,因为0与任何数都是0,。所以我们可以知道在n对应为0的位置,m必定为0,这里是固定的,但是在n为1的位置,m是任意取的,因为1与任何一个数最终答案是由最后那个数决定的。所以我们计算出n的二进制中有x个1,那么满足n&m==m的情况就有2的x次方种了,这时候的C_{n}^{m}\textrm{}  是为奇数的,m总共可取的有n+1种方案(0~n),所以答案就是(n+1)-2^x了

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值