AtCoder Regular Contest 066--C - Lining Up--规律+快速幂

C - Lining Up
Time Limit: 2 sec / Memory Limit: 256 MB
Score :  points
Problem Statement There are  people, conveniently numbered  through . They were standing in a row yesterday, but now they are unsure of the order in which they were standing. However, each person remembered the following fact: the absolute difference of the number of the people who were standing to the left of that person, and the number of the people who were standing to the right of that person. According to their reports, the difference above for person  is .
Based on these reports, nd the number of the possible orders in which they were standing. Since it can be extremely large, print the answer modulo . Note that the reports may be incorrect and thus there may be no consistent order. In such a case, print .
Constraints
Input The input is given from Standard Input in the following format:
         
Output Print the number of the possible orders in which they were standing, modulo .
Sample Input 1
5  2 4 4 0 2 
Sample Output 1

There are four possible orders, as follows:
Sample Input 2
7  6 4 0 2 4 0 2 
Sample Output 2

Any order would be inconsistent with the reports, thus the answer is .
Sample Input 3
300
N 1 N
i Ai
109 + 7 0
1 ≦ N ≦ 105 0 ≦ Ai ≦ N − 1
N A1 A2 ... AN
109 + 7
2,1,4,5,3 2,5,4,1,3 3,1,4,5,2 3,5,4,1,2
0
2019/5/27 AtCoder Regular Contest 066
https://atcoder.jp/contests/arc066/tasks_print 2/5
Sample Input 3
8  7 5 1 1 7 3 5 3 
Sample Output 3
16 

思路:
分情况考虑,先说不符合条件的情况,即n不为0,但是0出现了两次。再者是如果n是偶数,那么0不可以出现。

还有就是一个数字出现三次以上。

每一对分别来看,看成整体就是n/2,一共2*2*...(n/2个)那么就是答案了。

快速幂

#define ll long long
const ll mod=1e9+7;
ll pow_mod(ll a, ll n, ll m)
{
    if(n == 0) return 1;
    ll x = pow_mod(a, n/2, m);
    long long ans = (long long)x * x % m;
    if(n % 2 == 1) ans = ans *a % m;
    return ans;//
}
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
ll pow_mod(ll a, ll n, ll m)
{
    if(n == 0) return 1;
    ll x = pow_mod(a, n/2, m);
    long long ans = (long long)x * x % m;
    if(n % 2 == 1) ans = ans *a % m;
    return ans;//
}
int sum[600000];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        int v;
        scanf("%d",&v);
        sum[v]++;
        if(sum[v]>=3)
        {
            printf("0\n");//不符合情况一
            return 0;
        }
    }
    if(n&1)
    {
        //非0
        if(sum[0]!=1)
        {
            //0只能出现一次
            printf("0\n");
            return 0;
        }
    }
    if(!(n%2))
    {
        //n为偶数
        if(sum[0])
        {
            //0的个数不为0不符合条件
            printf("0\n");
            return 0;
        }
    }
    //每个数字可以有左右两种状态。
    printf("%lld\n",pow_mod(2,n/2,mod));
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值