P2312 解方程

题意:给出一个方程$a_0+a_1x+a_2x^2+...+a_nx^n=0$的系数所有系数$a_i$,求方程在$[1,m]$内的整数解

数据范围:

对于 30% 的数据:$0<n\le 2,|a_i|\le 100,a_n≠0,m<100$
对于 50% 的数据:$0<n\le 100,|a_i|\le 10^{100},a_n≠0,m<100$
对于 70% 的数据:$0<n\le 100,|a_i|\le 10^{10000},a_n≠0,m<10^4$
对于 100% 的数据:$0<n\le 100,|a_i|\le 10^{10000},a_n≠0,m<10^6$

看到瞬间。。。暴力高精。。。

但是x的次幂怎么处理?

有个叫秦九韶的大佬(瞎BB)

注意系数的符号

所以在高精数组里记录了一个fu

在加法时候判断一下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define int long long
#define olinr return
#define _ 0
#define love_nmr 0
#define DB double
struct node 
{
    int mp[50505];
    int len;
    int fu;
    node ()
    {
        memset(mp,0,sizeof mp);
        len=1;
        fu=1;
    }
    int &operator [] (int a)
    {
        return mp[a];
    }
    friend bool operator < (const node &a,const node &b)
    {
        if(a.len<b.len) return true;
        if(a.len>b.len) return false;
        for(int i=a.len;i>=1;i--)
        {
            if(a.mp[i]<b.mp[i]) return true;
            if(a.mp[i]>b.mp[i]) return false;
        }
        return true;
    }
    friend node operator + (const node &a,const node &b)
    {
        node t;
        t.len=max(a.len,b.len)+2;
        if(a.fu==b.fu)
        {
            for(int i=1;i<=t.len;i++)
            {
                t.mp[i]+=a.mp[i]+b.mp[i];
                t.mp[i+1]+=t.mp[i]/10;
                t.mp[i]%=10;
            }
            while(t.len>1&&t.mp[t.len]==0) t.len--;
            t.fu=a.fu;
        }
        if(a.fu!=b.fu)
        {
            if(b<a)
            {
                t.len=max(a.len,b.len);
                for(int i=1;i<=t.len;i++)
                {
                    t.mp[i]+=a.mp[i]-b.mp[i];
                    if(t.mp[i]<0)
                    {
                        t.mp[i]+=10;
                        t.mp[i+1]--;
                    }
                }
                t.fu=a.fu;
            }
            else
            {
                t.len=max(a.len,b.len);
                for(int i=1;i<=t.len;i++)
                {
                    t.mp[i]+=b.mp[i]-a.mp[i];
                    if(t.mp[i]<0)
                    {
                        t.mp[i]+=10;
                        t.mp[i+1]--;
                    }
                }
                t.fu=b.fu;
            }
            while(t.len>1&&t.mp[t.len]==0) t.len--;
        }
        return t;
    }
    void out()
    {
        if(fu==-1)
            putchar('-');
        for(int i=len;i>=1;i--)
            putchar(mp[i]+'0');
    }
    friend node operator * (const node &a,const node &b)
    {
        node t;
        t.len=a.len+b.len+2;
        for(int i=1;i<=a.len;i++)
            for(int j=1;j<=b.len;j++)
            {
                t.mp[i+j-1]+=a.mp[i]*b.mp[j];
                t.mp[i+j]+=t.mp[i+j-1]/10;
                t.mp[i+j-1]%=10;
            }
        while(t.len>1&&t.mp[t.len]==0) t.len--;
        t.fu=a.fu*b.fu;
        return t;
    }   
    void copy(const node &a)
    {
        len=a.len;
        for(int i=1;i<=len;i++)
            mp[i]=a.mp[len-i+1];
    }
};
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            f=-f;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
inline void put(int x)
{
    if(x<0)
    {
        x=-x;
        putchar('-');
    }
    if(x>9)
        put(x/10);
    putchar(x%10+'0');
}
int n;
int m;
int tot;
node a[150];
int ans[1050500];
inline bool ok(int xx)
{
    node x;
    x.len=0;
    while(xx)
    {
        x[++x.len]=xx%10;
        xx/=10;
    }
    node t;
    t=a[n];
    for(int i=n;i>=1;i--)
    {
        t=t*x+a[i-1];
    }
    if(t.len==1&&t[t.len]==0) return true;
    return false;
}
signed main()
{
    n=read();
    m=read();
    for(int i=0;i<=n;i++)
    {
        int f=1;
        node ls;
        ls.len=0;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            ls[++ls.len]=ch^48;
            ch=getchar();
        }
        a[i].copy(ls);
        a[i].fu=f;
    }
    for(int i=1;i<=m;i++)
    {
        if(ok(i))
            ans[++tot]=i;
    }
    put(tot);
    putchar('\n');
    for(int i=1;i<=tot;i++)
    {
        put(ans[i]);
        putchar('\n');
    }
    olinr ~~(0^_^0)+love_nmr;
}

然而这数据范围是承受不了的。。。。$O(n*m*高精)$

光是$n*m$就已经$10^8$了QAQ

所以,有个niubilitiful的东西--------取模啊

模一个大质数!

注意输入用快读

快读一边读一边模6666666

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define int long long
#define olinr return
#define _ 0
#define love_nmr 0
#define DB double
const int mod=1000000007LL;
int a[150];
int ans[1050000];
int tot;
int n;
int m;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            f=-f;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        x%=mod;
        ch=getchar();
    }
    return x*f;
}
inline void put(int x)
{
    if(x<0)
    {
        x=-x;
        putchar('-');
    }
    if(x>9)
        put(x/10);
    putchar(x%10+'0');
}
inline bool ok(int x)
{
    int t=a[n];
    for(int i=n;i>=1;i--)
        t=(t*x+a[i-1])%mod;
    if(t==0) return true;
    return false;
}
signed main()
{
    n=read();
    m=read();
    for(int i=0;i<=n;i++)
    {
        a[i]=read();
        a[i]%=mod;
    }
    for(int i=1;i<=m;i++)
    {
        if(ok(i))
            ans[++tot]=i;
    }
    put(tot);
    putchar('\n');
    for(int i=1;i<=tot;i++)
    {
        put(ans[i]);
        putchar('\n');
    }
    olinr ~~(0^_^0)+love_nmr;
}

注意,在秦九韶的时候,少取模!!会TLE

因为取模和除法一样,要调用系统库,(不信可以GDB单步执行)

速度自然慢了

原来用了5个取模

TLE3个点

减少了2个,居然快了400多msQAQ

索性在int之内减少更多

猜你喜欢

转载自www.cnblogs.com/olinr/p/9560385.html