[洛谷P2312]解方程:哈希+秦九韶算法

分析:

利用哈希的思想可以避免使用高精度。
枚举可能解时只需枚举到模数-1。

代码:

ZZ代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
typedef long long LL;

const LL MOD0=1e9+7;
const LL MOD1=1e8+9;
const LL MOD2=19260817;
int n,m;
int ans[1000005],tot;
LL a[105][3],ret[3];

inline void read(int i){
    LL f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){
        a[i][0]=((a[i][0]<<3)+(a[i][0]<<1)+ch-'0')%MOD0;
        a[i][1]=((a[i][1]<<3)+(a[i][1]<<1)+ch-'0')%MOD1;
        a[i][2]=((a[i][2]<<3)+(a[i][2]<<1)+ch-'0')%MOD2;
        ch=getchar();
    }
    if(f==-1){
        a[i][0]=(MOD0-a[i][0])%MOD0;
        a[i][1]=(MOD1-a[i][1])%MOD1;
        a[i][2]=(MOD2-a[i][2])%MOD2;
    }
}

void solve(int x,int pos){
    if(!pos) return;
    ret[0]=(ret[0]*x+a[pos-1][0])%MOD0;
    ret[1]=(ret[1]*x+a[pos-1][1])%MOD1;
    ret[2]=(ret[2]*x+a[pos-1][2])%MOD2;
    solve(x,pos-1);
}

bool check(int x){
    ret[0]=a[n][0];
    ret[1]=a[n][1];
    ret[2]=a[n][2];
    solve(x,n);
    return ret[0]==ret[1]&&ret[1]==ret[2]&&ret[2]==0;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++) read(i);
    for(int i=1;i<=m;i++)
        if(check(i)) ans[++tot]=i;
    printf("%d\n",tot);
    for(int i=1;i<=tot;i++)
        printf("%d\n",ans[i]);
    return 0;
}

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>

int n,m,a[105][6];
int prm[6]={0,24001,24007,24019,24023,24029};
int tag[1000005];

inline void read(int id){
    int f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){
        for(int i=1;i<=5;i++)
            a[id][i]=((a[id][i]<<3)+(a[id][i]<<1)+ch-'0')%prm[i];
        ch=getchar();
    }
    if(f==-1){
        for(int i=1;i<=5;i++)
            a[id][i]=(prm[i]-a[id][i])%prm[i];
    }
}       

int main(){
    scanf("%d%d",&n,&m);int ans=0;
    for(int i=0;i<=n;i++) read(i);
    for(int i=1;i<=5;i++){
        for(int j=0;j<prm[i];j++){
            int temp=a[n][i];
            for(int k=n-1;k+1;k--)
                temp=(temp*j+a[k][i])%prm[i];
            if(temp==0){
                for(int k=j;k<=m;k+=prm[i]){
                    tag[k]++;
                    if(tag[k]==5) ans++;
                }
            }
        }
    }
    printf("%d\n",ans);
    for(int i=1;i<=m;i++)
        if(tag[i]==5) printf("%d\n",i);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9666918.html