Hard to prepare 2018 徐州赛区网络预赛

题意:

  就是由2个数 每次选一个 可以选同样的 围成一个圈 使得相邻的数同或为真  求方案数

解析:

  第一个数有2种选择 之后的n-2个数 都有2k-1 种选择 第n个数 我们要考虑 它的左右两个数 是否一样 一样的话 就是2k - 1 种选择, 不一样的话就是2k - 2 种选择

  如果一样是不是就可以看作一共有n-1个数 求方案数。。所以递归一下就好了

  但左右两个数一样的情况 不还得乘上最后一种的2k-1吗  请看以下。。。解释。。

 

 

  

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 1000005, INF = 0x7fffffff, MOD = 1e9 + 7;
typedef long long LL;
int n, k;
LL c[maxn];
LL qp(LL a, LL b)
{
    LL res = 1;
    while(b)
    {
        if(b & 1) res = res * a % MOD;
        a = a * a % MOD;
        b >>= 1;
    }
    return res;
}

void init()
{
    c[0] = 1;
    for(int i=1; i<maxn; i++)
        c[i] = c[i-1] * 2 % MOD;    
}

LL dfs(int n, int k)
{
    if(n == 2)
        return c[k] * (c[k] - 1) % MOD;
    if(n == 1)
        return c[k];
        
    return (c[k] * (qp((c[k] - 1), n-2) % MOD) % MOD * (c[k] - 2) % MOD + dfs(n-2, k) % MOD) % MOD;
}


int main()
{
    init();
    int T;
    int n, k;
    scanf("%d", &T);
    while(T--)
    {
        cin>> n >> k;
        
        cout<< dfs(n, k) <<endl;
    }
    
    return 0;
}

 

posted @ 2018-09-10 15:03  WTSRUVF  阅读(161)  评论(0编辑  收藏  举报