Key Set 快速幂

题目:

soda has a set S with n integers {1,2,…,n}. A set is called key set if the sum of integers 
in the set is an even number. He wants to know how many nonempty subsets of S are key set.

Input

There are multiple test cases. The first line of input contains an integer T (1≤T≤105), 
indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤109), the number of integers in the set.

Output


For each test case, output the number of key sets modulo 1000000007.

Sample Input


4 1 2 3 4


Sample Output


0 1 3 7

关键是读懂这个题目的意思,他说一个集合有n个元素
问他有多少个子集的元素和为偶数;

思路:问题所在是这n个元素不值到时奇是偶,可以假设有A个偶数B个奇数,则A+B=n

那么只要他的子集在这B个奇数中选取偶数个的话,他的子集的元素和就一定为偶数;

所以满足条件的子集个数为

(c(0,B)+c(2,B)+c(4,B)+...+c(B-1,B))*(c(0,A)+c(1,A)+c(2,A)+...c(A,A))-1   //减一是因为排除A和B都没选即空集的情况;

=(2^(B-1))*(2^A)-1

=2^(A+B-1)-1

=2^(n-1)-1;
接下来就是写一个快速幂的事情了;

上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define ll long long
const int mod=1000000007;
int quick(int k){
    ll ans=1,base=2;
    while(k){
        if(k&1){
            ans=(ans*base)%mod;
        }
        base=(base*base)%mod;
        k>>=1;
    }
    ans=(ans+mod-1)%mod;//防止ans等于0的情况 
    return ans;
} 
int main(){
    int t;
    scanf("%d",&t);
    int n;
    while(t--){
        scanf("%d",&n);
        printf("%d\n",quick(n-1));
    }
    return 0;
}

 



posted @ 2020-07-22 20:54  Rain_luo  阅读(62)  评论(0编辑  收藏  举报