zoukankan      html  css  js  c++  java
  • bzoj3737 [Pa2013]Euler

    https://www.lydsy.com/JudgeOnline/problem.php?id=3737

    https://szkopul.edu.pl/problemset/problem/5LCCf9uDmKEBYhuzP7iT-8SM/site/?key=statement

    根据欧拉函数那个式子,设a分解质因数后为a1^p1*a2^p2*..*ak^pk,a的欧拉函数就等于(a1-1)*a1^(p1-1)*(a2-1)*a2^(p2-1)*..*(ak-1)*ak^(pk-1)

    那么,暴力枚举给出n的所有因子,将它们全部+1,然后只保留它们中的质数,那么x的质因子只可能在这些质数中产生

    这样的质数不多,爆搜就好了。。。当然如果n是1要特判一下,直接输出1和2

    好吧,直接爆搜会T飞。。。

    我在网上找到了解决方法:

    设当前还要构造出的欧拉函数值为nowphi,如果还要拆成两个或以上个数的积,那么其中最小数一定<=sqrt(nowphi);如果当前要考虑的最小的质数-1(是最小的可能的因子)也>sqrt(nowphi),那么自然不可能拆成两个或以上的个数的积

    现在唯一可能是nowphi单独作为一项存在;要求是,nowphi+1>=当前考虑质数(不然在其他情况会考虑到),且nowphi+1是质数

    这是一个大剪枝,可以A了。。。貌似复杂度还是有保证的?https://www.bbsmax.com/A/B0zq67P8Jv/

    讲不清楚。。。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<map>
      6 #include<cmath>
      7 using namespace std;
      8 #define fi first
      9 #define se second
     10 #define mp make_pair
     11 #define pb push_back
     12 typedef long long ll;
     13 typedef unsigned long long ull;
     14 typedef pair<ll,ll> pii;
     15 
     16 namespace M
     17 {
     18 //不会...板子先贴过来
     19 const ll prime[] = {2, 3, 7, 61, 24251};
     20 const ll MT = 5;
     21 inline ll mulmod(ll x, ll y, ll mod)
     22 {
     23     ll tmp=(x*y-ll((long double)x/mod*y+1.0e-8)*mod);
     24     return tmp<0?tmp+mod:tmp;
     25 }
     26 inline ll powermod(ll a, ll b, ll k)
     27 {
     28     ll re = 1, temp = a;
     29     while (b)
     30     {
     31         if (b & 1)
     32             re = mulmod(re, temp, k);
     33         temp = mulmod(temp, temp, k);
     34         b >>= 1;
     35     }
     36     return re;
     37 }
     38 ll TwiceDetect(ll a, ll b, ll k)
     39 {
     40     ll t = 0;
     41     ll x, y;
     42     while ((b & 1) == 0)
     43     {
     44         b >>= 1;
     45         t++;
     46     }
     47     y = x = powermod(a, b, k);
     48     while (t--)
     49     {
     50         y = mulmod(x, x, k);
     51         if (y == 1 && x != 1 && x != k - 1)
     52             return 0;
     53         x = y;
     54     }
     55     return y;
     56 }
     57 bool Miller_Rabin(ll n)
     58 {
     59     ll i;
     60     ll tmp;
     61     for (i = 0; i < MT; i++)
     62     {
     63         tmp = prime[i];
     64         if (n == prime[i])
     65             return true;
     66         if (TwiceDetect(tmp, n - 1, n) != 1)
     67             break;
     68     }
     69     return (i == MT);
     70 }
     71 }
     72 using M::Miller_Rabin;
     73 
     74 const ll N=1000000;
     75 bool nprime[1001000];
     76 ll prime[201000],len;
     77 bool isprime(ll x)
     78 {
     79     if(x>N)  return Miller_Rabin(x);
     80     else    return !nprime[x];
     81 }
     82 
     83 ll T;
     84 ll n;
     85 ll tt[1001],tp;
     86 ll an[1010100],tpa;
     87 void dfs(ll p,ll now,ll nowphi)
     88 {
     89     if(nowphi==1)
     90     {
     91         an[++tpa]=now;
     92         return;
     93     }
     94     if(p>tp) return;
     95     if(tt[p]-1>sqrt(nowphi))
     96     {
     97         if(nowphi+1>=tt[p]&&isprime(nowphi+1))
     98             an[++tpa]=now*(nowphi+1);
     99         return;
    100     }
    101     dfs(p+1,now,nowphi);
    102     if((long double)now*tt[p]>=1e18) return;
    103     now*=tt[p];
    104     if(nowphi%(tt[p]-1)!=0) return;
    105     nowphi/=(tt[p]-1);
    106     dfs(p+1,now,nowphi);
    107     while(1)
    108     {
    109         if((long double)now*tt[p]>=1e18) return;
    110         now*=tt[p];
    111         if(nowphi%tt[p]!=0) return;
    112         nowphi/=tt[p];
    113         dfs(p+1,now,nowphi);
    114     }
    115 }
    116 int main()
    117 {
    118     //freopen("/tmp/3737/7.in","r",stdin);
    119     //freopen("/tmp/3737/7.ans","w",stdout);
    120     ll i,j,ed;
    121     nprime[1]=1;
    122     for(i=2;i<=N;i++)
    123     {
    124         if(!nprime[i])  prime[++len]=i;
    125         for(j=1;j<=len&&i*prime[j]<=N;j++)
    126         {
    127             nprime[i*prime[j]]=1;
    128             if(i%prime[j]==0)   break;
    129         }
    130     }
    131     scanf("%lld",&T);
    132     while(T--)
    133     {
    134         scanf("%lld",&n);
    135         if(n==1)
    136         {
    137             puts("2");
    138             puts("1 2");
    139             continue;
    140         }
    141         tp=0;
    142         ed=sqrt(n+0.5);
    143         for(i=1;i<=ed;i++)
    144             if(n%i==0)
    145             {
    146                 if(isprime(i+1))    tt[++tp]=i+1;
    147                 if(ll(i)*i!=n&&isprime(n/i+1))  tt[++tp]=n/i+1;
    148             }
    149         sort(tt+1,tt+tp+1);
    150         tpa=0;dfs(1,1,n);
    151         sort(an+1,an+tpa+1);
    152         printf("%lld
    ",tpa);
    153         for(i=1;i<=tpa;i++)  printf("%lld%c",an[i]," 
    "[i==tpa]);
    154         if(!tpa)    puts("");
    155     }
    156     return 0;
    157 }

    耶,卡到第一了!

    卡常版代码:

      1 #pragma GCC optimize(3)
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<vector>
      6 #include<map>
      7 #include<cmath>
      8 using namespace std;
      9 #define fi first
     10 #define se second
     11 #define mp make_pair
     12 #define pb push_back
     13 typedef long long ll;
     14 typedef unsigned long long ull;
     15  
     16 namespace M
     17 {
     18 //不会...板子先贴过来
     19 const ll prime[] = {2, 3, 7, 61, 24251};
     20 const ll MT = 5;
     21 inline ll mulmod(ll x, ll y, ll mod)
     22 {
     23     ll tmp=(x*y-ll((long double)x/mod*y+1.0e-8)*mod);
     24     return tmp<0?tmp+mod:tmp;
     25 }
     26 inline ll powermod(ll a, ll b, ll k)
     27 {
     28     ll re = 1, temp = a;
     29     while (b)
     30     {
     31         if (b & 1)
     32             re = mulmod(re, temp, k);
     33         temp = mulmod(temp, temp, k);
     34         b >>= 1;
     35     }
     36     return re;
     37 }
     38 ll TwiceDetect(ll a, ll b, ll k)
     39 {
     40     ll t = 0;
     41     ll x, y;
     42     while ((b & 1) == 0)
     43     {
     44         b >>= 1;
     45         t++;
     46     }
     47     y = x = powermod(a, b, k);
     48     while (t--)
     49     {
     50         y = mulmod(x, x, k);
     51         if (y == 1 && x != 1 && x != k - 1)
     52             return 0;
     53         x = y;
     54     }
     55     return y;
     56 }
     57 bool Miller_Rabin(ll n)
     58 {
     59     ll i;
     60     ll tmp;
     61     for (i = 0; i < MT; i++)
     62     {
     63         tmp = prime[i];
     64         if (n == prime[i])
     65             return true;
     66         if (TwiceDetect(tmp, n - 1, n) != 1)
     67             break;
     68     }
     69     return (i == MT);
     70 }
     71 }
     72 using M::Miller_Rabin;
     73  
     74 const ll N=500000;
     75 bool nprime[501000];
     76 ll prime[200100],len;
     77 bool isprime(ll x)
     78 {
     79     return x>N?Miller_Rabin(x):!nprime[x];
     80 }
     81  
     82 ll tt[1001],*tp=tt;
     83 ll an[1010100],*tpa=an;
     84 ll now,nowphi;
     85 void dfs(ll *p,ll now,ll nowphi)
     86 {
     87     if(nowphi==1)
     88     {
     89         *(++tpa)=now;
     90         return;
     91     }
     92     if(p>tp) return;
     93     if(*p-1>sqrt(nowphi))
     94     {
     95         if(nowphi+1>=*p&&isprime(nowphi+1))
     96             *(++tpa)=now*(nowphi+1);
     97         return;
     98     }
     99     dfs(p+1,now,nowphi);
    100     //if((long double)now*(*p)>=1e18)    return;
    101     now*=(*p);
    102     if(nowphi%((*p)-1)!=0) return;
    103     nowphi/=((*p)-1);
    104     dfs(p+1,now,nowphi);
    105     while(1)
    106     {
    107         //if((long double)now*(*p)>=1e18)    return;
    108         now*=(*p);
    109         if(nowphi%(*p)!=0)  return;
    110         nowphi/=(*p);
    111         dfs(p+1,now,nowphi);
    112     }
    113 }
    114 int T;
    115 ll n;
    116 int main()
    117 {
    118     //freopen("/tmp/3737/18.in","r",stdin);
    119     //freopen("/tmp/3737/18.ans","w",stdout);
    120     int i,j,ed;
    121     nprime[1]=1;
    122     for(i=2;i<=N;i++)
    123     {
    124         if(!nprime[i])  prime[++len]=i;
    125         for(j=1;j<=len&&i*prime[j]<=N;j++)
    126         {
    127             nprime[i*prime[j]]=1;
    128             if(i%prime[j]==0)   break;
    129         }
    130     }
    131     scanf("%d",&T);
    132     while(T--)
    133     {
    134         scanf("%lld",&n);
    135         if(n==1)
    136         {
    137             puts("2");
    138             puts("1 2");
    139             continue;
    140         }
    141         tp=tt;
    142         ed=sqrt(n+0.5);
    143         for(i=1;i<=ed;i++)
    144             if(n%i==0)
    145             {
    146                 if(isprime(i+1))    *(++tp)=i+1;
    147                 if(ll(i)*i!=n&&isprime(n/i+1))  *(++tp)=n/i+1;
    148             }
    149         sort(tt+1,tp+1);
    150         tpa=an;dfs(tt+1,1,n);
    151         sort(an+1,tpa+1);
    152         int ttttt=tpa-an;
    153         printf("%d
    ",ttttt);
    154         for(i=1;i<=ttttt;i++)  printf("%lld%c",an[i]," 
    "[i==ttttt]);
    155         if(!ttttt)    puts("");
    156     }
    157     return 0;
    158 }
    View Code

    https://www.luogu.org/problemnew/show/P4780

    减弱版?

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 #include<map>
      6 #include<cmath>
      7 using namespace std;
      8 #define fi first
      9 #define se second
     10 #define mp make_pair
     11 #define pb push_back
     12 typedef long long ll;
     13 typedef unsigned long long ull;
     14 typedef pair<ll,ll> pii;
     15 
     16 namespace M
     17 {
     18 //不会...板子先贴过来
     19 const ll prime[] = {2, 3, 7, 61, 24251};
     20 const ll MT = 5;
     21 inline ll mulmod(ll x, ll y, ll mod)
     22 {
     23     ll tmp=(x*y-ll((long double)x/mod*y+1.0e-8)*mod);
     24     return tmp<0?tmp+mod:tmp;
     25 }
     26 inline ll powermod(ll a, ll b, ll k)
     27 {
     28     ll re = 1, temp = a;
     29     while (b)
     30     {
     31         if (b & 1)
     32             re = mulmod(re, temp, k);
     33         temp = mulmod(temp, temp, k);
     34         b >>= 1;
     35     }
     36     return re;
     37 }
     38 ll TwiceDetect(ll a, ll b, ll k)
     39 {
     40     ll t = 0;
     41     ll x, y;
     42     while ((b & 1) == 0)
     43     {
     44         b >>= 1;
     45         t++;
     46     }
     47     y = x = powermod(a, b, k);
     48     while (t--)
     49     {
     50         y = mulmod(x, x, k);
     51         if (y == 1 && x != 1 && x != k - 1)
     52             return 0;
     53         x = y;
     54     }
     55     return y;
     56 }
     57 bool Miller_Rabin(ll n)
     58 {
     59     ll i;
     60     ll tmp;
     61     for (i = 0; i < MT; i++)
     62     {
     63         tmp = prime[i];
     64         if (n == prime[i])
     65             return true;
     66         if (TwiceDetect(tmp, n - 1, n) != 1)
     67             break;
     68     }
     69     return (i == MT);
     70 }
     71 }
     72 using M::Miller_Rabin;
     73 
     74 const ll N=1000000;
     75 bool nprime[1001000];
     76 ll prime[201000],len;
     77 bool isprime(ll x)
     78 {
     79     if(x>N)  return Miller_Rabin(x);
     80     else    return !nprime[x];
     81 }
     82 
     83 ll T;
     84 ll n;
     85 ll tt[1001],tp;
     86 ll an=0x3f3f3f3f3f3f3f3f;
     87 void dfs(ll p,ll now,ll nowphi)
     88 {
     89     if(nowphi==1)
     90     {
     91         an=min(an,now);
     92         return;
     93     }
     94     if(p>tp) return;
     95     if(tt[p]-1>sqrt(nowphi))
     96     {
     97         if(nowphi+1>=tt[p]&&isprime(nowphi+1))
     98             an=min(an,now*(nowphi+1));
     99         return;
    100     }
    101     dfs(p+1,now,nowphi);
    102     if((long double)now*tt[p]>2147483648) return;
    103     now*=tt[p];
    104     if(nowphi%(tt[p]-1)!=0) return;
    105     nowphi/=(tt[p]-1);
    106     dfs(p+1,now,nowphi);
    107     while(1)
    108     {
    109         if((long double)now*tt[p]>2147483648) return;
    110         now*=tt[p];
    111         if(nowphi%tt[p]!=0) return;
    112         nowphi/=tt[p];
    113         dfs(p+1,now,nowphi);
    114     }
    115 }
    116 int main()
    117 {
    118     //freopen("/tmp/3737/7.in","r",stdin);
    119     //freopen("/tmp/3737/7.ans","w",stdout);
    120     ll i,j,ed;
    121     nprime[1]=1;
    122     for(i=2;i<=N;i++)
    123     {
    124         if(!nprime[i])  prime[++len]=i;
    125         for(j=1;j<=len&&i*prime[j]<=N;j++)
    126         {
    127             nprime[i*prime[j]]=1;
    128             if(i%prime[j]==0)   break;
    129         }
    130     }
    131     scanf("%lld",&n);
    132     if(n==1)
    133     {
    134         puts("1");
    135         return 0;
    136     }
    137     tp=0;
    138     ed=sqrt(n+0.5);
    139     for(i=1;i<=ed;i++)
    140         if(n%i==0)
    141         {
    142             if(isprime(i+1))    tt[++tp]=i+1;
    143             if(ll(i)*i!=n&&isprime(n/i+1))  tt[++tp]=n/i+1;
    144         }
    145     sort(tt+1,tt+tp+1);
    146     dfs(1,1,n);
    147     if(an<2147483648)    printf("%lld",an);
    148     else    printf("%d",-1);
    149     return 0;
    150 }
    View Code
  • 相关阅读:
    产品经理应该知道的那点事儿(1)
    C语言的前世今生
    “隔代教育的成功之道”新浪教育专家宋少卫做客西单图书大厦
    【9.21更新】跟踪报道TopLanguage关于《深入理解计算机系统(第2版)》一书翻译问题 的讨论
    中国要做物联网技术的强国,而非大国
    关于时钟芯片DS1302的问题
    stm32开发问题集锦
    keil 中使用c++的注意事项
    iar atof 问题
    IAR生成HEX文件
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9556479.html
Copyright © 2011-2022 走看看