zoukankan      html  css  js  c++  java
  • poj3708:函数式化简+高精度进制转换+同余方程组

    题目大意

    给定一个函数

    找出满足条件

      等于 k

    的最小的x

     m,k,d已知 其中 m,k 很大需要使用高精度存储

    思路:

    对 函数f(m)进行化简 ,令t=ceil( log(d,m) )

    可以得到 f(m)=d ^ t * ( a [ m / (d^t) ] ) + d ^ (t-1) * ( b[ m/( d^(t-1) ) ] )......+b [m%d] ;

    我们一看,每一项都是 跟 d 的次方有关,所以考虑使用 d 进制进行计算

    设     m=a1b1b2b3b4(d进制)

    那么  f(m)=a[a1]b[b2]b[b3]b[b4](d进制)

    以此类推

    fx(m)=k,即 m通过 x次上述变换后得到了k (这里的 m 和 k 均为 d 进制)

    于是 我们可以找到 m 每一位第一次等于k的情况以及这一位的循环节 分别存在数组中

    那么问题就转化为了解同余方程

    这个题还有很多无解的情况,需要注意特判

    代码:

    #include <iostream>
    #include <stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<string>
    #include<ctype.h>
    using namespace std;
    #define MAXN     100000
    char m[110];
    char k[110];
    long long p[110];
    long long q[110];
    long long start[1000];
    long long ans[1000];
    long long res[1000];
    long long mm[1000];
    long long kk[1000];
    long long a[1000];
    long long b[1000];
    long long d;
    long long vi[110];
    long long getnum(char c)
    {
        return c-'0';
    }
    void trans(char* str,long long base0,long long base1)
    {
        memset(res,0,sizeof(res));
        long long y,i,j;
        start[0]=strlen(str);
        for(i=1;i<=start[0];i++)
        {
            start[i]=getnum(str[i-1]);
        }
        while(start[0]>=1)
        {
            y=0; //余数
            ans[0]=start[0];
            for(i=1;i<=start[0];i++)
            {
                y=y*base0+start[i];
                ans[i]=y/base1;
                y%=base1;
            }
            res[++res[0]]=y;  //这一轮的余数
            i=1;
            while(i<=ans[0]&&ans[i]==0)
                i++;
            memset(start,0,sizeof(start));
            for(j=i;j<=ans[0];j++)
                start[++start[0]]=ans[j];
            memset(ans,0,sizeof(ans));
        }
        return;
    }
    long long save(long long *dis)
    {
        for(long long i=res[0];i;i--)
        {
            dis[res[0]-i]=res[i];
        }
        return res[0];
    }
    long long exgcd(long long a,long long b,long long &x,long long &y)
    {
        if(!b)
        {
            x=1;
            y=0;
            return a;
        }
        long long tt=exgcd(b,a%b,x,y);
        long long t;
        t=x;
        x=y;
        y=(t-a/b*y);
        return tt;
    }
    long long solve(long long r)
    {
        long long a1,a2,b1,b2,x,y,A,B,C,d,t;
        a1=a[0];
        b1=b[0];
        for(long long i=1;i<r;i++)
        {
            a2=a[i];
            b2=b[i];
            A=a1;
            B=a2;
            C=b2-b1;
            d=exgcd(A,B,x,y);
            if(C%d)
            {
                return -1;
            }
            t=B/d;
            x=(x*(C/d)%t+t)%t;
            b1=a1*x+b1;
            a1=a1/d*a2;
        }
        return b1;
    }
    int main()
    {
        while(scanf("%lld",&d),d!=-1)
        {
            for(long long i=1;i<d;i++)
                scanf("%lld",p+i);
            for(long long i=0;i<d;i++)
                scanf("%lld",q+i);
            scanf("%s%s",m,k);
            trans(m,10,d);
            long long nm=save(mm);
            trans(k,10,d);
            long long nk=save(kk);
            if(nm!=nk)
            {
                puts("NO");
                continue;
            }
            memset(a,-1,sizeof(a));
            memset(b,-1,sizeof(b));
            bool have=1;
            for(long long i=0;i<nm;i++)
            {
                bool ok=0;
                long long tmp=0;
                memset(vi,0,sizeof(vi));
                for(long long j=mm[i];;)
                {
                    if(j==kk[i])
                    {
                        if(ok==0)
                        {
                            b[i]=tmp;
                            ok=1;
                        }
                        else
                        {
                            a[i]=tmp-b[i];
                            break;
                        }
                    }
                    tmp++;
                    if(i==0)
                        j=p[j];
                    else
                        j=q[j];
                    if(tmp>=5000)
                    {
                        ok=0;
                        break;
                    }
                }
                if(!ok)
                {
                    have=0;
                    break;
                }
            }
            if(!have)
            {
                puts("NO");
                continue;
            }
            long long ans=solve(nm);
            if(ans==-1)
            {
                puts("NO");
                continue;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    (iOS)项目总结-项目中遇到的各种的问题和解决方法
    iOS ---不一样的NSLog打印(精准打印)
    iOS 之 Cocoapods安装
    iOS--关于同步下载
    iOS--NSTimer设置定时器的两种方法
    iOS--创建炫酷的渐变色界面
    Mac OS安装 OpenCV(python3)
    使用ADB无线连接Android真机进行调试
    Hexo 添加 SEO
    如何得体跳槽
  • 原文地址:https://www.cnblogs.com/oneshot/p/3990783.html
Copyright © 2011-2022 走看看