牛客网NC81-20.7.20(快速幂?)

题意:有n个人,排成一排,给一个数组a, a[i]代表第i个人左右两边的人的差值,问有多少种排法。
输入:人数n,差值数组a[] (1<=n<=1e6,0<=a[i]<=1e6)
输出:排法数mod(1e9+7)
分析
若n为奇数:除了中间一个是0,以中间为分界,差值对称且是每次加2的偶数,例:6、4、2、0、2、4、6。
若n为偶数:以中间为分界,差值对称且是每次加2的奇数,例:5、3、1、1、3、5
本来除了n为奇数时中间一个人没得选,其他时候对于每个人来说都有两个位置选,所以有2(n/2)种选法。为什么不是2(n)种,因为差值相同的人确定了一个另一个也随之确定.

思路:对n==1特判,对a[i]的值检测是否符合标准。然后可以快速幂求2^(n/2)…好像也可以不用快速幂暴力求也能过

代码:`

import java.util.*;


public class Solution {
    /**
     * 
     * @param n int整型 
     * @param a int整型一维数组 
     * @return int整型
     */
    static int maxn=(int)1e6+5;
    static int Mod=(int)1e9+7;
    public int solve (int n, int[] a) {
        // write code here
        int[] arr=new int[maxn];
        for(int v:a)arr[v]++;
        if(n%2==0){
            for(int i=0;i<n;i++){
                if(i%2==0&&arr[i]!=0)return 0;
                if(i%2==1&&arr[i]!=2)return 0;
            }
        }
        else{
            if(arr[0]!=1)return 0;
            if(n==1)return 1;
            for(int i=1;i<n;i++){
                if(i%2==0&&arr[i]!=2)return 0;
                if(i%2==1&&arr[i]!=0)return 0;
            }
        }
        int hh=n/2;
        long ans=1,muti=2;
        while(hh>0){
            if(hh%2==1)ans=ans*muti%Mod;
            muti=muti*muti%Mod;
            hh/=2;
        }
        return (int)ans;
    }
}`
ps:又是摸鱼的一天

你可能感兴趣的:(牛客网NC81-20.7.20(快速幂?))