牛客网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:又是摸鱼的一天
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值