zoukankan      html  css  js  c++  java
  • kuangbin专题 数论基础 part1?

    线段树专题太难了,那我来做数学吧!

    但数学太难了,我......(扯

    这两天想了做了查了整理了几道数学。

    除了一些进阶的知识,像莫比乌斯反演,杜教筛,min25学不会我跳了,一些基础的思维还是可以记录一下。

    ex_gcd 

    POJ 1061 青蛙的约会
    POJ 2115 C Looooops

    SGU 106 The equation

    三连击。

    谈谈理解吧,原理我没懂 (扯

    就是通过exgcd求出来的gcd(a,b)=d,而c%d!=0说明无解。

    再将a,b,c分别除以公约数d。 a/=d,b/=d,c/=d;

    exgcd出来x=1,  x*=c就是一个特解。其中x的最小正解(这里包括0)是 (x%b+b)%b;  此时的y可以相应用 y=(c-a*x)/b 反过来求解得到。

    同理 y的最小正解相应可得到,y*=c 再 (y%a+a)%a;

    这里要特别注意尽量让a,b初始都是正的,而且特别注意要保证 ax+by=c这样的式子的形式,特别是c的位置,c负的没关系。

    通解就可以通过特解加 任意个单位  ,比如 x=x0+b*k;  y=y0-a*k;   

    什么什么解系?我线代忘啦(哭

    然后SGU 106 注意如果每个参数负的,对应算出来的k区间要swap一下。因为你看那个负号在分母上呀。

    还要用到ceil 和floor   。一直以来说精度误差,我都不想用这个函数,后来还是屈服了。

    UVA 11752 The Super Powers

    这题我思维呀,虽然我岔了。手玩一下,发现指数为合数就能成为答案。

    然后我一开始想用优先队列!对素数的合数次幂加入答案。然后就没了,WA了好一阵子。

    其实合数的合数次幂也存在答案啊,比如6^4,可以搞成6^(2*2 || 1*4) 并且这个是前面没出现的!所以啊 要处理所有的数的答案。用set维护,不能用优先队列了。

    判溢出的细节

    这我没想到啊,题目是ull,一直想根据负数或者数变小了来判,难搞的很。

    还是看了题解才知道,用ull的上限,每次除这个数,预处理出每个数最多的指数的次幂,最多指数次幂都小于4(最小的合数)了,就break掉。

    别头铁判溢出啊,反过来处理最多指数到几,这就很有灵性对吧。(我没有...

    LightOJ 1370 Bi-shoe and Phi-shoe

    POJ 2478 Farey Sequence

    两个欧拉筛,我几个月的进步就是把我模板的筛从log升级到线性了红红火火恍恍惚惚。线性的还好理解,但min25和杜教目前必不可能懂555.

    UVA 11426 GCD - Extreme (II)

    这题好经典啊感觉。我只能想到预处理欧拉函数,对每个i 根号n的去找因数 那n^3/2就没了啊。

    然后又发现了新大陆思维,对每个数去找因数,是不好找的一个过程,但你对每个因数去算他对别的数产生的贡献是很好搞的!

    再有一个gcd的公式  我要对每个n找满足x与n 的gcd为i的个数,gcd(n,x)=i  ,gcd(n/i,x/i)=1;  这不是phi[n/i]! 每个因数的贡献就转化为了  i*phi[n/i]

    然后就有了对因数1,2,3,4,5......  去加贡献    n+n/2+n/3+n/4+n/5+.....+1+....+0这个总复杂度咋算啊,md我居然不会,反正比上面的优秀多了

    还有,既可以像我注释里一样,统计sum【i】,O(1)回答,这样预处理的复杂度就为上面那个式子;大概500ms;

    还查到了别人对欧拉函数求了前缀和,然后直接对每个数O(n)统计,这个需要理解一下。只用200ms左右;

     1 #include <bits/stdc++.h>
     2 #define debug(x) cout << #x << ": " << x << endl
     3 using namespace std;
     4 typedef long long ll;
     5 const int INF=0x3f3f3f3f;
     6 const int MOD=1e9+7;
     7 
     8 
     9 const int MAXN=4e6+7;
    10 
    11 bool notprime[MAXN];
    12 //ll sum[MAXN];
    13 //ll b[MAXN];
    14 ll prime[MAXN/10];
    15 ll phi[MAXN];
    16 int cnt;
    17 
    18 void getprime_phi()
    19 {
    20     cnt = 0;
    21     phi[1] = 1;
    22     notprime[0]=notprime[1]=1;
    23     for(int i = 2;i < MAXN;i++)
    24     {
    25         if(!notprime[i])
    26         {
    27             prime[cnt++] = i;
    28             phi[i] = i-1;
    29         }
    30         for(int j = 0;j < cnt && i * prime[j] < MAXN;j++)
    31         {
    32             notprime[i*prime[j]] = 1;
    33             if(i%prime[j]==0)
    34             {
    35                 phi[i*prime[j]] = phi[i]*prime[j];
    36                 break;
    37             }
    38             phi[i*prime[j]] = phi[i]*(prime[j]-1);
    39         }
    40     }
    41     for(int i=2;i<MAXN;++i) phi[i]+=phi[i-1];
    42 }
    43 
    44 int main()
    45 {
    46     getprime_phi();
    47     /*for(int i=1;i<MAXN;++i)
    48     {
    49         for(int j=i*2;j<MAXN;j+=i)
    50         {
    51             b[j]+=1ll*phi[j/i]*i;
    52         }
    53     }
    54 
    55     for(int i=2;i<MAXN;++i)
    56         sum[i]=sum[i-1]+b[i];*/
    57     int n;
    58     while(~scanf("%d",&n))
    59     {
    60         if(!n) break;
    61        // printf("%lld
    ",sum[n]);
    62         ll ans=0;
    63         for(int i=1;i<=n;++i) ans+=1ll*(phi[n/i]-1)*i;
    64         printf("%lld
    ",ans);
    65     }
    66     return 0;
    67 }
    View Code

    POJ 2116 Death to Binary?

    模拟题

    将计算字符串的值  和 值转化字符串 封装成函数。

    还是string好用,对未赋值的string,不能通过下标访问,但可以用+=,直接粘在后面,贼棒,我一开始用char 数组,好难搞的啊。

    然后我这题没注意到输入可以为0,没测,然后出现了output limit exceed!活久见。然后发现自己原来的转化写假了,没特判0。就会输出贼多0,就没了,居然不是WA而是。

    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    #define debug(x) cout << #x << ": " << x << endl
    using namespace std;
    typedef long long ll;
    const int MAXN=100;
    const int INF=0x3f3f3f3f;
    const int MOD=1e9+7;
    
    ll f[60];
    void init()
    {
        f[0]=1;f[1]=2;
        for(int i=2;i<50;++i) f[i]=f[i-2]+f[i-1];
    }
    
    string s,t,ss,tt,goa;
    
    ll cal(string &str)
    {
        ll res=0;
        int len=str.size();
        for(int i=0;i<len;++i)
        {
            if(str[i]=='1') res+=f[len-i-1];
        }
        return res;
    }
    
    void standard(string &tmp, ll val)
    {
        tmp="";
        for(int i=40;i>=0;--i)
        {
            if(val>=f[i])
            {
                val-=f[i];
                tmp+='1';
            }
            else if(tmp!="")
            {
                tmp+='0';
            }
        }
        if(tmp=="") tmp="0";
    }
    
    int main()
    {
        init();
        while(cin>>s>>t)
        {
            ll anss=cal(s);
            standard(ss,anss);
    
            ll anst=cal(t);
            standard(tt,anst);
    
            ll ans=anss+anst;
            //debug(ans);
            standard(goa,ans);
            int len=goa.size();
            int lens=ss.size();
            int lent=tt.size();
    
            for(int i=0;i<len+2-lens;++i) cout<<' ';
            cout<<ss<<'
    ';
            cout<<"+ ";
            for(int i=0;i<len-lent;++i) cout<<' ';
            cout<<tt<<'
    ';
            cout<<"  ";
            for(int i=0;i<len;++i) cout<<'-';
            cout<<'
    ';
            cout<<"  "<<goa<<'
    '<<'
    ';
        }
        return 0;
    }
    
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    #define debug(x) cout << #x << ": " << x << endl
    using namespace std;
    typedef long long ll;
    const int MAXN=100;
    const int INF=0x3f3f3f3f;
    const int MOD=1e9+7;
    
    ll f[60];
    void init()
    {
        f[0]=1;f[1]=2;
        for(int i=2;i<50;++i) f[i]=f[i-2]+f[i-1];
    }
    
    string s,t,ss,tt,goa;
    
    ll cal(string &str)
    {
        ll res=0;
        int len=str.size();
        for(int i=0;i<len;++i)
        {
            if(str[i]=='1') res+=f[len-i-1];
        }
        return res;
    }
    
    void standard(string &tmp, ll val)
    {
        tmp="";
        for(int i=40;i>=0;--i)
        {
            if(val>=f[i])
            {
                val-=f[i];
                tmp+='1';
            }
            else if(tmp!="")
            {
                tmp+='0';
            }
        }
        if(tmp=="") tmp="0";
    }
    
    int main()
    {
        init();
        while(cin>>s>>t)
        {
            ll anss=cal(s);
            standard(ss,anss);
    
            ll anst=cal(t);
            standard(tt,anst);
    
            ll ans=anss+anst;
            //debug(ans);
            standard(goa,ans);
            int len=goa.size();
            int lens=ss.size();
            int lent=tt.size();
    
            for(int i=0;i<len+2-lens;++i) cout<<' ';
            cout<<ss<<'
    ';
            cout<<"+ ";
            for(int i=0;i<len-lent;++i) cout<<' ';
            cout<<tt<<'
    ';
            cout<<"  ";
            for(int i=0;i<len;++i) cout<<'-';
            cout<<'
    ';
            cout<<"  "<<goa<<'
    '<<'
    ';
        }
        return 0;
    }
    View Code

    UVA 10200 Prime Time

    这都WA我,根号n试除法判素数即可,查了居然WA在精度,不知道啥道理。

    记住,当不得不使用除法,浮点数需要保留几位小数四舍五入be rounded to,且你WA了,可以加个小的eps??? 

    总结:

    然后除了欧拉筛的模板题,其他好像都或多或少查了题解。

    不过还是坚持想了,自己实现了,WA了T了才去查的。

    只是感叹自己还是TCL,还要加油啊。算法竞赛本来就是需要经验积累的嘛!

  • 相关阅读:
    OGG实验:喂奶间隔数据表通过OGG配置同步
    Oracle Exadata 学习笔记之核心特性Part1
    js 表格指定列,根据相同值实现跨行合并
    tr td同时添加点击事件
    Oracle 分页查询
    tomcat启动时运行指定的java类
    application/x-www-form-urlencoded与multipart/form-data与application/json的区别 精析
    nodejs中thiskeyword的问题
    AlphaGo 开源项目研究(1)
    LeetCode -- Best Time to Buy and Sell Stock II
  • 原文地址:https://www.cnblogs.com/Zzqf/p/12074590.html
Copyright © 2011-2022 走看看