【poj1186】 方程的解数

http://poj.org/problem?id=1186 (题目链接)

题意:已知一个n元高次方程: 
 
其中:x1, x2,…,xn是未知数,k1,k2,…,kn是系数,p1,p2,…pn是指数。且方程中的所有数均为整数。 
假设未知数1 <= xi <= M, i=1,,,n,求这个方程的整数解的个数。

solution 
  meet in the middle。移项,分两部分搜索,hash判断两次dfs的结果是否相同,统计结果。

代码:

// poj1186
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define MOD 10000007
#define LL long long
#define inf 2147483640
#define Pi 3.1415926535898
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

struct hash {int w,next,num;}h[100000010];

int cnt,ans,n,m,head[MOD],p[10],k[10],pd[1010][1010];

void dfs1(int x,int w) {
    if (x>n/2) {
        int i=abs(w)%MOD;
        bool flag=1;
        for (int j=head[i];j;j=h[j].next) if (w==h[j].w) {h[j].num++;flag=0;break;}
        if (flag) {h[++cnt].w=w;h[cnt].next=head[i];head[i]=cnt;h[cnt].num++;}
    }
    else
        for (int i=1;i<=m;i++) dfs1(x+1,w+k[x]*pd[i][p[x]]);
}
void dfs2(int x,int w) {
    if (x>n) {
        int i=abs(w)%MOD;
        for (int j=head[i];j;j=h[j].next) if (-w==h[j].w) {ans+=h[j].num;break;}
    }
    else
        for (int i=1;i<=m;i++) dfs2(x+1,w+k[x]*pd[i][p[x]]);
}
int main() {
    scanf("%d%d",&n,&m);
    for (int i=0;i<=m;i++) {
        pd[i][0]=1;
        for (int j=1;j<=m;j++) pd[i][j]=pd[i][j-1]*i;
    }
    for (int i=1;i<=n;i++) scanf("%d%d",&k[i],&p[i]);
    dfs1(1,0);
    dfs2(n/2+1,0);
    printf("%d",ans);
    return 0;
}

  

时间: 2024-08-06 01:22:17

【poj1186】 方程的解数的相关文章

方程的解数(codevs_1735)——hash

这题挺简单的吧,其实只需要一步--就可以把暴力搜索的m^6降到m^3--那就是--请看代码 #include<iostream> #include<cstdio> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>

codevs1735 方程的解数(meet in the middle)

题意 题目链接 Sol 把前一半放在左边,后一半放在右边 meet in the middle一波 统计答案的时候开始想的是hash,然而MLE了两个点 实际上只要排序之后双指针扫一遍就行了 #include<bits/stdc++.h> using namespace std; const int MAXN = 7, MAX = 1e7 + 10; int K[MAXN], P[MAXN], N, M, ans; int a1[MAX], c1, a2[MAX], c2, cnt[MAX];

hdu 1186(搜索+HASH)

方程的解数 Time Limit: 15000MS   Memory Limit: 128000K Total Submissions: 7045   Accepted: 2417 Case Time Limit: 5000MS Description 已知一个n元高次方程: 其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数.且方程中的所有数均为整数. 假设未知数1 <= xi <= M, i=1,,,n,求这个方程的整数解的个数. 1 &

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

搜索专讲

搜索专讲 Tags:搜索 https://www.zybuluo.com/xzyxzy/note/1058215 前言 做一个专题肯定是要花点时间的 但是哇,搜索怎么这么多内容?!WTF?! 好吧慢慢刷,待四五月份左右出pdf或ppt的讲义吧 先把题目放上,大家愿意的和我一起做吧 题目 李老师给了一个包 广搜 [x] ?POJ1426-Find The Multiple https://vjudge.net/problem/POJ-1426 [x] POJ2251-Dungeon Master

认识数学各个分支

数论 人类从学会计数开始就一直和自然数打交道了,后来由于实践的需要,数的概念进一步扩充,自然数被叫做正整数,而把它们的相反数叫做负整数,介于正整数和负整数中间的中性数叫做0.它们和起来叫做整数. 对于整数可以施行加.减.乘.除四种运算,叫做四则运算.其中加法.减法和乘法这三种运算,在整数范围内可以毫无阻碍地进行.也就是说,任意两个或两个以上的整数相加.相减.相乘的时候,它们的和.差.积仍然是一个整数.但整数之间的除法在整数范围内并不一定能够无阻碍地进行. 人们在对整数进行运算的应用和研究中,逐步

POI 10.28

[POI2015]KUR 不考虑构造原串再匹配 考虑开始位置满足什么条件才能匹配. 显然,开始位置确定,后面的字符都确定了. 而且,a,n互质,所以必然能遍历n的剩余系,从不同位置开始,初始的a*s+b mod n的值互不相同. 设初始点为s,x=a*s+b mod n 由上分析可知,s,x一 一对应. x开始的第i位就是:x+(i-1)*b % n 如果满足条件,对于m位中的每一位, 如果m这一位是0,有:x+(i-1)*b mod n<p 否则有p<=x+(i-1)*b mod n <

meet-in-the-middle 基础算法(优化dfs)

$meet-in-the-middle$(又称折半搜索.双向搜索)对于$n<=40$的搜索类型题目,一般都可以采用该算法进行优化,很稳很暴力. $meet-in-the-middle$算法的主要思想是将搜索区域化为两个集合,分别由搜索树的两端向中间扩展,直到搜索树产生交集,此时即可得到我们的合法情况. 通常适用于求经过$n$步变化,从A集合变到B集合需要的方案数问题. 对于普通dfs来说,其一大弊端是随着搜索层数的不断增加,搜索的复杂度也会极速增长, 而$meet-in-the-middle$算

组合计数小练

组合数学什么的,最有趣了呢-- [51nod 1251] Fox序列的数量 题意 求满足以下条件的序列数目: 序列长度为 $ n $ ,每个元素都属于 $ [1,m] \cap Z $ : 这个序列单调不降: 这个序列出现次数最多的数是唯一的. 数据范围: $ 1≤n,m≤100000 $ ,答案对 $ 1e9+7 $ 取模 题解 先枚举出现次数最多的数的出现次数 $ k $ ,我们要计算的是 $ x_1+x_2+...+x_{m-1}=n-k, ; x_i≤k-1 $ 的非负整数解数目. 可以