BZOJ3751: [NOIP2014]解方程

既然bzoj上有这道题了就把这个坑填了吧。。。

题解见:http://blog.csdn.net/popoqqq/article/details/40984859

话说这个解法如果当时想到冲突的概率很小的话应该就能想出来233

代码:

  1 #include<cstdio>
  2
  3 #include<cstdlib>
  4
  5 #include<cmath>
  6
  7 #include<cstring>
  8
  9 #include<algorithm>
 10
 11 #include<iostream>
 12
 13 #include<vector>
 14
 15 #include<map>
 16
 17 #include<set>
 18
 19 #include<queue>
 20
 21 #include<string>
 22
 23 #define inf 1000000000
 24
 25 #define maxn 100000
 26
 27 #define maxm 500+100
 28
 29 #define eps 1e-10
 30
 31 #define ll long long
 32
 33 #define pa pair<int,int>
 34
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42
 43 #define mod 1000000007
 44
 45 using namespace std;
 46
 47 inline int read()
 48
 49 {
 50
 51     int x=0,f=1;char ch=getchar();
 52
 53     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 54
 55     while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}
 56
 57     return x*f;
 58
 59 }
 60 int n,m,tot,ans[1005],a[1005][10],f[1000000][10];
 61 const int p[5]={10007,11261,14843,19997,21893};
 62 char s[10000+5];
 63
 64 int main()
 65
 66 {
 67
 68     freopen("input.txt","r",stdin);
 69
 70     freopen("output.txt","w",stdout);
 71
 72     n=read();m=read();
 73     for0(i,n)
 74     {
 75         scanf("%s",s+1);int len=strlen(s+1);bool flag=0;
 76         for1(j,len)
 77         {
 78             if(s[j]==‘-‘)flag=1;
 79             else for0(k,4)a[i][k]=(a[i][k]*10+s[j]-‘0‘)%p[k];
 80         }
 81         if(flag)for0(k,4)a[i][k]=p[k]-a[i][k];
 82     }
 83     //for0(i,n)for0(j,4)cout<<i<<‘ ‘<<j<<‘ ‘<<a[i][j]<<endl;
 84     for0(j,4)
 85      for0(i,p[j]-1)
 86       {
 87         f[i][j]=0;
 88         for3(k,n,0)f[i][j]=(f[i][j]*i+a[k][j])%p[j];
 89       }
 90     for1(i,m)
 91     {
 92         int j;
 93         for(j=0;j<5;j++)
 94          if(f[i%p[j]][j])break;
 95         if(j==5)ans[++tot]=i;
 96     }
 97     printf("%d\n",tot);
 98     for1(i,tot)printf("%d\n",ans[i]);
 99
100     return 0;
101
102 } 

还有加强版的,觉得没什么意思了。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define M 110
 6 using namespace std;
 7 typedef long long ll;
 8 const int prime[]={30011,11261,14843,19997,10007,21893};
 9 int n,m,stack[1001001],top;
10 int ans[110],tot;
11 ll a[M][6],f[30011][6];
12 inline ll F(int x,int j)
13 {
14     int i;
15     ll re=0;
16     for(i=n;~i;i--)
17         re=(re*x+a[i][j])%prime[j];
18     return re;
19 }
20 inline void Input(int x)
21 {
22     static char s[10100];
23     int i,j;
24     bool flag=false;
25     scanf("%s",s+1);
26     for(i=1;s[i];i++)
27     {
28         if(s[i]==‘-‘)
29             flag=true;
30         else
31             for(j=0;j<6;j++)
32                 a[x][j]=( (a[x][j]<<1) + (a[x][j]<<3) + s[i]-‘0‘ )%prime[j];
33     }
34     if(flag)
35         for(j=0;j<6;j++)
36             a[x][j]=prime[j]-a[x][j];
37 }
38 int main()
39 {
40
41     //freopen("equation.in","r",stdin);
42
43     int i,j;
44     cin>>n>>m;
45     for(i=0;i<=n;i++)
46         Input(i);
47
48     for(j=0;j<6;j++)
49         for(i=0;i<prime[j];i++)
50             f[i][j]=F(i,j);
51
52     for(i=0;i<prime[0];i++)
53     {
54         if(f[i%prime[0]][0]==0)
55             stack[++top]=i;
56     }
57
58     for(i=1;i<=top;i++)
59     {
60         if(stack[i]+prime[0]>m)
61             break;
62         stack[++top]=stack[i]+prime[0];
63     }
64
65     for(i=1;i<=top;i++)
66     {
67         if(stack[i]>m)
68             break;
69         for(j=1;j<6;j++)
70             if(f[stack[i]%prime[j]][j])
71                 break;
72         if(j==6)
73             ans[++tot]=stack[i];
74     }
75
76     cout<<tot<<endl;
77     for(i=1;i<=tot;i++)
78         printf("%d\n",ans[i]);
79 }

时间: 2024-10-10 00:42:58

BZOJ3751: [NOIP2014]解方程的相关文章

BZOJ3751 NOIP2014 解方程(Hash)

题目链接  BZOJ3751 这道题的关键就是选取取模的质数. 我选了4个大概几万的质数,这样刚好不会T 然后统计答案的时候如果对于当前质数,产生了一个解. 那么对于那些对这个质数取模结果为这个数的数也要统计进答案. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i &g

bzoj3751: [NOIP2014]解方程 数学

题解:http://www.cnblogs.com/mhy12345/p/4109764.html 我也不知道该怎么选质数才比较优越,但是可以用秦九韶算法优化常数,就容易过了. #include<bits/stdc++.h> using namespace std; int f[5]={ 16253,21139,22433,23059,27647 }; int a[5][101]; bool v[5][100000]; char t[10057]; int cnt,st[1000001]; b

【秦九韶算法】【字符串哈希】bzoj3751 [NOIP2014]解方程

在模意义下枚举m进行验证,多设置几个模数,而且小一些,利用f(x+p)%p=f(x)%p降低计算次数.UOJ AC,bzoj OLE. #include<cstdio> #include<iostream> #include<cstring> #include<vector> using namespace std; #define MAXV 4951 vector<int>v; typedef unsigned int ull; const u

【BZOJ 3751】 [NOIP2014]解方程

3751: [NOIP2014]解方程 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 914  Solved: 173 [Submit][Status][Discuss] Description 已知多项式方程: a0+a1*x+a2*x^2+...+an*x^n=0 求这个方程在[1,m]内的整数解(n和m均为正整数). Input 第一行包含2个整数n.m,每两个整数之间用一个空格隔开. 接下来的n+1行每行包含一个整数,依次为a0,a1,

【bzoj3751】[NOIP2014]解方程 数论

题目描述 已知多项式方程: a0+a1*x+a2*x^2+...+an*x^n=0 求这个方程在[1,m]内的整数解(n和m均为正整数). 输入 第一行包含2个整数n.m,每两个整数之间用一个空格隔开. 接下来的n+1行每行包含一个整数,依次为a0,a1,a2,...,an. 输出 第一行输出方程在[1,m]内的整数解的个数. 接下来每行一个整数,按照从小到大的顺序依次输出方程在[1,m]内的一个整数解. 样例输入 2 10 2 -3 1 样例输出 2 1 2 题解 真心不难的数论题 首先高精度

NOIP2014解方程

题目:求一个n次整系数方程在1-m内的整数解  n<=100 系数<=10000位 m<=100W 题解:最暴力的想法是枚举x,带入求值看是否为0. 这样涉及到高精度乘高精度,高精度乘单精度,高精度加高精度和高精度减高精度. 复杂度 n*m*len*len ,显然只能过30%的数据 让我们考虑优化: 我们先来研究一下这个算法的主要耗时在哪里 1)将x带入方程左边求值 2)选择多少x带入 我们考虑第一个优化 1)秦九韶算法 只要我们把原方程左边化为 ((An*x+An-1)*x+An-2)

noip2014 解方程(本博文转载于http://blog.csdn.net/popoqqq/article/details/40984859,略有删减)

首先阿贝尔在200年前告诉我们 五次以上方程没有求根公式 于是我们只能枚举1~m 这个是100W 然后100W再加上1W位的精度 都不用运算直接就是跪…… 怎么办呢QAQ 哈希大法好! 令f(x)=an*x^n+...+a1*x^1+a0*x^0 易知若f(x)=0 则f(x) mod p=0 反之如果f(x) mod p=0 那么我们基本可以得出f(x)=0 p比较靠谱的时候碰撞率极低 所以我们把所有的ai都对p取模 然后对于每个解O(n)验证即可 这样是O(m*n)=10 8 (不是一秒么

[BZOJ 3751][NOIP2014]解方程(哈希)

Description 已知多项式方程: a0+a1*x+a2*x^2+...+an*x^n=0 求这个方程在[1,m]内的整数解(n和m均为正整数). Solution 一道很久很久以前就应该做的noip的题 一定要放上来是要见证我人品崩坏的一下午 生无可恋…QAQ 题解其实也很简单啦 随便找几个素数取模验证是不是等于0就好了 随便 随便 随便 随便找几个…素数 在WA\TLE\OLE间切换,最后还是抄了别人的几个素数 怀疑人生[望天 (BZOJ上的数据是加强了的,如果是ccf的数据那当然就随

[noip2014]解方程 hash+秦九昭

坑啊= = 选了好几次质数,发现还是这一组靠谱 思路:每次mod之后求出所有解,再mod再求,看着复杂度差不多了就把没重复的都输出就行了 const mi:array[1..7] of int64=(12537,15437,17647,14677,10003,10009,10007); var n,m,shi,sum,x:int64; i,j,k,y1:longint; a:array[-1..102,-1..10000+9] of int64; flag:array[-1..1000000+9