天天看點

HDU 5363 Key Set(快速幂) Key Set

Key Set

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Problem Description 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
        

Source 2015 Multi-University Training Contest 6  

題意:給你一個具有n個元素的集合S{1,2,…,n},問集合S的非空子集中元素和為偶數的非空子集有多少個。

放入出題人的解題報告

HDU 5363 Key Set(快速幂) Key Set

解題思路:因為集合S中的元素是從1開始的連續的自然數,是以所有元素中奇數個數與偶數個數相同,或比偶數多一個。另外我們要知道偶數+偶數=偶數,奇數+奇數=偶數,假設現在有a個偶數,b個奇數,則

HDU 5363 Key Set(快速幂) Key Set

根據二項式展開公式

HDU 5363 Key Set(快速幂) Key Set

以及二項式展開式中奇數項系數之和等于偶數項系數之和的定理

可以得到上式

HDU 5363 Key Set(快速幂) Key Set
HDU 5363 Key Set(快速幂) Key Set

最後的結果還需減去

HDU 5363 Key Set(快速幂) Key Set

即空集的情況,因為題目要求非空子集

是以最終結果為

HDU 5363 Key Set(快速幂) Key Set

由于n很大,是以計算n次方的時候需要用到快速幂,不然會TLE

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
#define ll __int64
using namespace std;
const int N = 50;
const int inf = 1000000000;
const int mod = 1000000007;
void Quick_Mod(ll a, ll b, ll mod)
{
    ll res = 1,term = a % mod;
    while(b)
    {
        if(b & 1) res = (res * term) % mod;
        term = (term * term) % mod;
        b >>= 1;
    }
    printf("%I64d\n",res-1);
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        Quick_Mod(2,n-1,mod);
    }
    return 0;
}
           

菜鳥成長記