zoukankan      html  css  js  c++  java
  • bzoj 3751: [NOIP2014]解方程 同余系枚举

    3.解方程
    (equation.cpp/c/pas)
    【问题描述】
    已知多项式方程:
    a ! + a ! x + a ! x ! + ⋯ + a ! x ! = 0
    求这个方程在[1, m]内的整数解(n 和 m 均为正整数)。
    【输入】
    输入文件名为 equation.in。
    输入共 n+2 行。
    第一行包含 2 个整数 n、m,每两个整数之间用一个空格隔开。
    接下来的 n+1 行每行包含一个整数,依次为a ! , a ! , a ! , ... , a ! 。
    【输出】
    输出文件名为 equation.out。
    第一行输出方程在[1, m]内的整数解的个数。
    接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。
    【输入输出样例 1】
    equation.in equation.out
    2 10 1
    1 1
    -2
    1
    【输入输出样例 2】
    equation.in equation.out
    2 10 2
    2 1
    -3 2
    1
    【输入输出样例 3】
    equation.in equation.out
    2 10 0
    1
    3
    2
    第 5 页共 6 页提高组 day2
    全国信息学奥林匹克联赛(NOIP2014)复赛
    【数据说明】
    对于 30%的数据,0 < n ≤ 2, a ! ≤ 100,a ! ≠ 0, m ≤ 100;
    对于 50%的数据,0 < n ≤ 100, a ! ≤ 10 !"" ,a ! ≠ 0,m ≤ 100;
    对于 70%的数据,0 < n ≤ 100, a ! ≤ 10 !"""" ,a ! ≠ 0,m ≤ 10000;
    对于 100%的数据,0 < n ≤ 100, a ! ≤ 10 !"""" ,a ! ≠ 0,m ≤ 1000000。

      考场上想到了在同余系中枚举x,但是对于最后30%数据用的自然溢出,自然溢出很容易被卡掉。其实这种做法已经十分贴近正解了。观察发现,取质数p,对于解a,b,若a==b(mod p)那么他们带入算出的值一定相同,所以只用取多个较小p,预处理出[0,p-1]的值,在枚举[1,m]代入检验即可,bzoj数据很不良心啊,要么TLE,要么WA,jason_yu帮我检查了半天,才发现由于ans=(ans * i + a[ii][j])%pmod;我写成了{ans=(ans+x*a[j])%pmod;x=x*i%pmod;}常数过大,所以时限内尝试质数个数过少。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    #define PROB "equation"
    #define MAXN 1100001
    #ifdef WIN32
    #define LL "%I64d"
    #else
    #define LL "%lld"
    #endif
    typedef long long qword;
    const int mod[5] = 
    {22861,22871,22877,22901,22907
    };
    int a[11][110];
    bool ok[MAXN];
    bool ok2[5][30000];
    char s[10010];
    int n,m;
    void work();
    int main()
    {
            freopen(PROB".in","r",stdin);
            freopen(PROB".out","w",stdout);
            int ii,i,j, k;
            int x;
            scanf("%d%d
    ",&n,&m);
            int ll = 4;
            for (ii=0;ii<=n;ii++)
            {
            //        scanf("%s", s);
                    fgets(s,sizeof(s),stdin);
                    int l = strlen(s)-1;
                    if((s[l-1]<'0' || s[l-1]>'9') && s[l-1]!='-')l--;
                    for(int j = 0; j < ll; j ++){
                            int pmod = mod[j];
                            a[j][ii] =0;
                            x=1;
                            k=0;
                            if (s[k]=='-')k++,x=-x;
                            else if (s[k]=='+')k++;
                            for (;k<l;k++)
                            {
                                    a[j][ii]=(a[j][ii]*10+s[k]-'0')%pmod;
                            
                            }
                            a[j][ii]=a[j][ii]*x%pmod;
                            if(a[j][ii] < 0)
                                a[j][ii] += pmod;
                    }
            }
            memset(ok,1,sizeof(ok));
            memset(ok2,1,sizeof(ok2));
            int pmod;
            int ans;
            for (ii=0;ii<ll;ii++)
            {
                    pmod=mod[ii];
                    for (i=0;i<pmod;i++)
                    {
                            ans=0;
                            for (j=n;j>=0;j--)
                            {
                                    ans=(ans * i + a[ii][j])%pmod;
                            }
                            if (ans)
                            {
                                    ok2[ii][i]=false;
                            }
                    }
            }
            int cnt = 0;
            for (int i=1;i<=m && cnt <= n;i++)
            {
                    for (int j=0;j<ll;j++)
                    {
                            if (!ok2[j][i%mod[j]]){
                                    ok[i]=false;
                                    break;
                            }
                    }
                    if(ok[i])
                        ++ cnt;
            }
            printf("%d
    ",cnt);
            for (i=1;i<=m;i++)
                    if (ok[i])
                            printf("%d
    ",i);
            return 0;
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    C:把算术表达式分成Token
    JavaScript数据结构——链表的实现与应用
    JavaScript数据结构——队列的实现与应用
    JavaScript数据结构——栈的实现与应用
    由“RangeError: Invalid status code: 0”错误所引发的思考
    工作是最好的投资——图书摘录
    Node.js在指定的图片模板上生成二维码图片并附带底部文字说明
    苹果手机对网页上样式为position:fixed的弹窗支持不好的解决办法
    自定义react数据验证组件
    Ubuntu 18.04中截图工具Shutter的编辑按钮不可用的解决办法
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4109764.html
Copyright © 2011-2022 走看看