Codeforces 327E. Axis Walking

output

standard output

Iahub wants to meet his girlfriend Iahubina. They both live in Ox axis (the horizontal axis). Iahub lives at point 0 and Iahubina at point d.

Iahub has n positive integers a1, a2, ..., an. The sum of those numbers is d. Suppose p1, p2, ..., pn is a permutation of {1, 2, ..., n}. Then, let b1 = ap1, b2 = ap2 and so on. The array b is called a "route". There are n! different routes, one for each permutation p.

Iahub's travel schedule is: he walks b1 steps on Ox axis, then he makes a break in point b1. Then, he walks b2 more steps on Ox axis and makes a break in point b1 + b2. Similarly, at j-th (1 ≤ j ≤ n) time he walks bj more steps on Ox axis and makes a break in point b1 + b2 + ... + bj.

Iahub is very superstitious and has k integers which give him bad luck. He calls a route "good" if he never makes a break in a point corresponding to one of those k numbers. For his own curiosity, answer how many good routes he can make, modulo 1000000007(109 + 7).

Input

The first line contains an integer n (1 ≤ n ≤ 24). The following line contains n integers: a1, a2, ..., an (1 ≤ ai ≤ 109).

The third line contains integer k (0 ≤ k ≤ 2). The fourth line contains k positive integers, representing the numbers that give Iahub bad luck. Each of these numbers does not exceed 109.

Output

Output a single integer — the answer of Iahub's dilemma modulo 1000000007 (109 + 7).

Examples

input

Copy

3
2 3 5
2
5 7

output

Copy

1

input

Copy

3
2 2 2
2
1 3

output

Copy

6

Note

In the first case consider six possible orderings:

  • [2, 3, 5]. Iahub will stop at position 2, 5 and 10. Among them, 5 is bad luck for him.
  • [2, 5, 3]. Iahub will stop at position 2, 7 and 10. Among them, 7 is bad luck for him.
  • [3, 2, 5]. He will stop at the unlucky 5.
  • [3, 5, 2]. This is a valid ordering.
  • [5, 2, 3]. He got unlucky twice (5 and 7).
  • [5, 3, 2]. Iahub would reject, as it sends him to position 5.

In the second case, note that it is possible that two different ways have the identical set of stopping. In fact, all six possible ways have the same stops: [2, 4, 6], so there's no bad luck for Iahub.

题意 :给n个数的一个序列n<=24再给出k个序列k<=2问n个数的全排列中前缀和不出现给的这k个数中的任意一个的排列种数有多少种, 一开始想到阶乘的种数上去了后来看题解是二进制状态压缩枚举出现的次数然后暴力的。

首先二进制暴力的时候位为1表示出现过了然后用一个数组来表示前缀和通过判断这个数组和K个数是否相等来判断是否要更新计数的数组。更新的方法为把当前所有位为1的数分别当做最后一位进行累加比如111就通过110,101,011这三个状态转移过来因为是从小到大枚举嘛前面的状态肯定也是这样过来的不会漏掉,如果说前置状态存在K里的某一种情况那么dp之前肯定也不会操作他那他就是0也就是没记录他

#include <iostream>
#include <cstdio>
#include <set>
#include <map>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
const long long int inf=1e9+7;
long long int dp[1<<24],dp1[1<<24];
int d[3];
long long lowbit(int x){
    return x&(-x);
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        memset(dp1,0,sizeof(dp1));
        for(int i=0;i<n;i++){
            int x;
            cin>>x;
            dp1[1<<i]=x;
        }
        int k;
        scanf("%d",&k);
        for(int i=1;i<=k;i++){
            scanf("%d",&d[i]);
        }
        long long ans=1<<n;
        dp[0]=1;
        for(long long  i=1;i<ans;i++){
            dp1[i]=dp1[i-lowbit(i)]+dp1[lowbit(i)];
            if(dp1[i]==d[1]||dp1[i]==d[2])
                continue;
            for(long long  j=i;j;j-=lowbit(j)){
                long long k=i-lowbit(j);
                dp[i]+=dp[k];
                if(dp[i]>inf)
                    dp[i]-=inf;
            }
        }

        cout<<dp[ans-1]<<endl;
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值