zoukankan      html  css  js  c++  java
  • [XJOI]noip40 T2统计方案

    统计方案

    小B写了一个程序,随机生成了n个正整数,分别是a[1]..a[n],他取出了其中一些数,并把它们乘起来之后模p,得到了余数c。但是没过多久,小B就忘记他选了哪些数,他想把所有可能的取数方案都找出来。你能帮他计算一下一共有多少种取数方案吗?请把最后的方案数模1000000007后输出。
    小B记得他至少取了一个数。

    输入格式:

    第一行三个正整数n,p,c,含义如题目所述。
    接下来一行有n个正整数,表示生成的n个随机数。

    输出格式:

    一个数,方案数模1000000007。

    样例输入:

    2 7 2

    1 2

    样例输出:

    2

    数据范围:

    对于30%的数据,n ≤ 16
    另有30%的数据,p ≤ 10000
    对于100%的数据,n ≤ 32, p ≤ 10^9, c ≤ 10^9, a[i] < p, p是质数
     
    解题思路:
    看到这种n <=32的数据范围,其实很多大佬都可以猜到这是中途相遇法
    ***如果知道这个的可以跳过下面这段介绍
    中途相遇法:事实上就是进行两次dfs,在第一次dfs时记录下搜索到的结果,
    一般用map或者hash,然后第二次是在dfs结束时根据上一次的结果,记录答案
    ***然后是对于这道题的介绍
    你先dfs前(n/2)个数,选或不选,结束时记录这些数的乘积a,我是用map来记录的
    然后在dfs后(n/2)个数,同样是选或不选,结束时得到这些数的乘积为b
    因为a*b%p=c,所以我们可以用(c/b)在%p意义下的逆元就是a的值
    最后再返回到原来的map里面找
    如果没看懂,可以借助程序在思考一下
    ***注意:(1)因为不能不取,所以在c=1的时候,答案要减一
    (2)c有可能大于等于p,这种情况直接输出0
    %:pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #define int long long
    #define czx 1000000007
    using namespace std;
    int ans=0,a[50],n,p,c,m;
    map <int,int> mp;
    int pow(int a){
        int res=1,b=p-2;
        while (b){
            if (b&1) res=(res*a)%p; b/=2; a=(a*a)%p;
        }
        return res;
    }
    inline void dfs(int x,int s){
        if (x==m+1){
            mp[s]++; return;
        }
        dfs(x+1,s); dfs(x+1,1ll*s*a[x]%p);
    }
    inline void dfs1(int x,int s){
        if (x==n+1){
            int a=c*pow(s)%p;
            ans=(ans+mp[a])%czx; return;
        }
        dfs1(x+1,s); dfs1(x+1,1ll*s*a[x]%p);
    }
    main(){
        scanf("%lld%lld%lld",&n,&p,&c);
        if (c>=p){
            puts("0"); return 0;
        }
        for (int i=1;i<=n;++i)
            scanf("%lld",&a[i]);
        m=n/2; dfs(1,1); dfs1(m+1,1);
        if (c==1) ans--; printf("%lld",ans);
    }
    View Code

    最后再给上几道中途相遇法的题目

  • 相关阅读:
    (原)Lazarus 异构平台下多层架构思路、DataSet转换核心代码
    (学)新版动态表单研发,阶段成果3
    (学) 如何将 Oracle 序列 重置 清零 How to reset an Oracle sequence
    (学)XtraReport WebService Print 报错
    (原)三星 i6410 刷机 短信 无法 保存 解决 办法
    (原) Devexpress 汉化包 制作工具、测试程序
    linux下网络配置
    apache自带ab.exe小工具使用小结
    Yii::app()用法小结
    PDO使用小结
  • 原文地址:https://www.cnblogs.com/logic-yzf/p/7576308.html
Copyright © 2011-2022 走看看