Game of Dice Gym - 101532E 折半搜索

本文介绍了一种使用折半搜索算法解决特定骰子乘积问题的方法。问题要求计算不同方式的数量,使n个特殊骰子的点数乘积模1e9+7等于给定值x。通过将问题转化为配对问题并利用快速幂计算逆元来降低复杂度。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<map>
#define LL long long
using namespace std;
const int MOD=1e9+7;
int diec[20][10];
map<LL,int> M;
long long ans=0;
int x;
long long pow(long long x,int n)
{
    long long y=1;
    long long u=x%MOD;
    while(n)
    {
        if(n&1) y=y*u%MOD;
        n>>=1;
        u=u*u%MOD;
    }
    return y;
}
void dfs(int s,int e,int flag,long long res)
{
    if(e==s)
    {
        if(flag)
        {
            ++M[res];
        }
        else
        {
            ans+=M[x*pow(res,MOD-2)%MOD];
        }
    }
    else
    {
        for(int i=0;i<6;i++)
        {
            dfs(s+1,e,flag,res*diec[s][i]%MOD);
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans=0;
        M.clear();
        int n;
        scanf("%d%d",&n,&x);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<6;j++)
            {
                scanf("%d",&diec[i][j]);
            }
        }
        dfs(0,n/2,1,1);
        dfs(n/2,n,0,1);
        cout<<ans<<endl;
    }
}

It is always fun to play with dice, here is one interesting game:

You are given n fair dice with 6 faces, the faces does not necessarily have values from 1 to 6 written on them. instead, they can have any values from 1 to 100 written on them.

Suppose you threw the n dice one after another, let us define the result of the throws as the multiplication of the numbers you get from each dice mod 109 + 7.

You task is to find how many different ways you can get the result of the dice throws equal to x.


Input

The first line contains an integer T, where T is the number of test cases.

The first line of each test case contains two integers n and x (1 ≤ n ≤ 14) (0 ≤ x < 109 + 7), where n is the number of the dice and x is the required result from the throws.

Then n lines follow, the ith line contains 6 integers fi1, fi2, ..., fi6 (1 ≤ fij ≤ 100), giving the values of ith dice's faces.

Output

For each test case, print a single line containing how many different ways you can get the result of the dice throws equal to x

Example
Input
3
3 9
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
5 6
1 2 9 9 9 9
1 2 9 9 9 9
1 3 9 9 9 9
1 3 9 9 9 9
1 6 9 9 9 9
5 999999937
100 1 1 1 1 1
100 1 1 1 1 1
100 1 1 1 1 1
100 1 1 1 1 1
100 1 1 1 1 1
Output
3
5
1

题意: 你有n个骰子,每个骰子的六个面已经给出,问你有多少种可能 使得这些骰子投出的数的乘积对1e9+7取模后=x、


一个裸的折半搜索题。

一开始想直接暴搜,然后发现复杂度高达6^14 肯定过不了。

然后发现这是个配对问题,所以可以用折半搜索。

对前半部分用map存一下搜索后的结果。

然后后半部分搜索时配对一下就行。

由于涉及到除法取模,快速幂求一下逆元就好。

复杂度应该是6^(n/2)再乘个log。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值