zoukankan      html  css  js  c++  java
  • [折半搜索][哈希]POJ1186方程的解数

    题目传送门

    这道题明显N数据范围非常小,但是M很大,所以用折半搜索实现搜索算法的指数级优化,将复杂度优化到O(M^(N/2))。

    将搜出的两半结果用哈希的方式合并(乘法原理)。

    Code:

    #include <cstdio>
    #include <algorithm>
    #define Kss 10000000
    using namespace std;
    
    int N,hf,kl[11],kr[11],pl[11],pr[11],M;
    int Gl[Kss],Gr[Kss],Cl,Cr;
    
    int ksm(int x,int y){int Res=1;while(y){if(y&1)Res*=x;x*=x;y>>=1;}return Res;}
    
    void searchl(int x,int tot){
        if(x==hf+1){Gl[++Cl]=tot;return ;}
        for(int i=1;i<=M;i++)searchl(x+1,tot+kl[x]*ksm(i,pl[x]));
    }
    
    void searchr(int x,int tot){
        if(x==N-hf+1){Gr[++Cr]=tot;return ;}
        for(int i=1;i<=M;i++)searchr(x+1,tot+kr[x]*ksm(i,pr[x]));
    }
    
    int Ans=0;
    int hs[Kss],Cts[Kss];
    
    void hash(int x){int k=x>0?x:-x;k%=Kss;while(hs[k]!=x&&hs[k]!=-2e9)k=k%Kss+1;hs[k]=x,Cts[k]++;}
    int find(int x){int k=x>0?x:-x;k%=Kss;while(hs[k]!=x&&hs[k]!=-2e9)k=k%Kss+1;return Cts[k];}
    
    int main()
    {
        scanf("%d%d",&N,&M);
        for(int i=0;i<Kss;i++)hs[i]=-2e9;
        hf=N>>1;
        for(int i=1;i<=hf;i++)scanf("%d%d",&kl[i],&pl[i]);
        for(int i=1;i<=N-hf;i++)scanf("%d%d",&kr[i],&pr[i]);
        searchl(1,0),searchr(1,0);
        for(int i=1;i<=Cr;i++)Gr[i]=-Gr[i];
        for(int i=1;i<=Cl;i++)hash(Gl[i]);
        for(int i=1;i<=Cr;i++)Ans+=find(Gr[i]);
        printf("%d",Ans);
        return 0;
    }
  • 相关阅读:
    ASP脚本获取服务器全部参数列表说明
    HTML基础教程
    HTML5代码大全
    CSS 属性大全
    Web前端单词大全
    css常用代码大全
    曾国藩:诚敬静谨恒!
    鼠标经过显示菜单
    月入3000+项目
    右侧菜单显示隐藏
  • 原文地址:https://www.cnblogs.com/Cptraser/p/9168455.html
Copyright © 2011-2022 走看看