zoukankan      html  css  js  c++  java
  • BZOJ3884 上帝与集合的正确用法(欧拉函数)

      设f(n)为模n时的答案,由2k mod n=2k mod φ(n)+φ(n) mod n(并不会证),且k mod φ(n)=f(φ(n)),直接就可以得到一个递推式子。记搜一发即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 10000010
    int T,n,f[N],phi[N],prime[N>>3],cnt=0;
    bool flag[N];
    int ksm(int a,int k,int p)
    {
        int s=1;
        for (;k;k>>=1,a=1ll*a*a%p) if (k&1) s=1ll*s*a%p;
        return s;
    }
    int calc(int n)
    {
        if (~f[n]) return f[n];
        return f[n]=ksm(2,calc(phi[n])+phi[n],n);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3883.in","r",stdin);
        freopen("bzoj3883.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        flag[1]=1;phi[1]=1;
        for (int i=2;i<=N-10;i++)
        {
            if (!flag[i]) prime[++cnt]=i,phi[i]=i-1;
            for (int j=1;j<=cnt&&prime[j]*i<=N-10;j++)
            {
                flag[prime[j]*i]=1;
                if (i%prime[j]==0) {phi[prime[j]*i]=phi[i]*prime[j];break;}
                else phi[prime[j]*i]=phi[i]*(prime[j]-1);
            }
        }
        memset(f,255,sizeof(f));f[1]=f[2]=0;
        T=read();
        while (T--)
        {
            n=read();
            printf("%d
    ",calc(n));
        }
        return 0;
    }
  • 相关阅读:
    数组和字符串//寻找数组的中心索引
    队列&栈//钥匙和房间
    队列&栈//01 矩阵
    队列&栈//图像渲染
    队列&栈//字符串解码
    队列&栈//用队列实现栈
    队列&栈//二叉树的中序遍历
    队列&栈//目标和
    队列&栈//克隆图
    队列&栈//逆波兰表达式求值
  • 原文地址:https://www.cnblogs.com/Gloid/p/9743851.html
Copyright © 2011-2022 走看看