• gmoj 6832.world


    Description

    世界可以抽象成一个长度为偶数n 且元素互不相同的数列a。每当发生了一些意外,他都会相应的产生一些变化,并成为一个新的数列a′,并且它们满足以下关系:

    如果这个数列正好经过n 次变换后首次回到最初始的数列a ,这个世界便是幸运的。此时的幸运值是n;如果没有回到最初始的序列,幸运值便是0。
    那如果,这个序列的长度在[2,A] 之间的偶数内均匀随机时,请你告诉我,世界期望的幸运值是多少呢?

    Input

    输入一行一个正整数A,其意义见【题目描述】。

    Outout

    输出一行一个实数,表示我的幸运值的期望,请保留5 位小数。

    Solution

    对于第i个位置,经过k次变换后到达的位置应该是(i imes2^k \% (n+1))

    而对于第一个位置到达的的位置就是(2^k \%(n+1))

    所以回到第一个位置即(2^kequiv1(mod n+1))

    所以现在要求的是这个最小的k

    根据欧拉定理,(2^{phi(n+1)}equiv1(mod n+1))

    所以如果(phi(n+1)) 小于n,则n就不会是最小的k

    因为当n+1为质数是(phi(n+1)) 才会是n,所以当n+1为质数时才判断这个n

    但这个n不一定是最小的

    当n不是最小的时候,最小的一定是n的因数(讲真挺好证的,画个图,因为(y=2^x mod (n+1))这东西的y是循环的,所以要使刚好在n那等于1,则最小的那个数应该是n的因数)

    把n分解质因数,最多就8个数,所以时间复杂度(O(8n)) 可以接受

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define N 10000001
    #define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
    using namespace std;
    int i,j,cnt,tot,n,x,ma,prime[N],a[N],last[N];
    long long ans;
    bool bz[N];
    long long ksm(long long x,int y,int MO)
    {
        long long sum=1;
        while (y)
        {
            if (y&1)sum=sum*x%MO;
            x=x*x%MO;
            y>>=1;
        }
        return sum;
    }
    int main()
    {
        open("world");
        scanf("%d",&n);
        for (i=2;i<=n;i++)
        {
            if (!bz[i]) prime[++tot]=i;
            for (j=1;j<=tot;j++)
            {
                if (prime[j]*i>n) break;
                bz[prime[j]*i]=1;
                last[prime[j]*i]=prime[j];
                if (i%prime[j]==0) break;
            }
        }
        for (i=2;i<=n;i+=2)
        {
            if (bz[i+1]) continue;
            x=i;
            ma=0;
            if (ksm(2,i,i+1)==1) ma=i;
            while (last[x])
            {
                cnt=last[x];
                while (x%cnt==0) x/=cnt;
                if (ksm(2,i/cnt,i+1)==1) 
                {
                	ma=i/cnt;
                	break;
    			}
            }
            if (x>1) 
    		{
    			if (!ma) ma=i/x;else
    			if (ksm(2,i/x,i+1)==1 && ma==i) ma=i/x;
    		}
            if (ma==i) ans+=i;
        }
        printf("%.5Lf",ans/(long double)(n/2));
        return 0;
    }
    
    
    如果自己说什麽都做不到而什麽都不去做的话,那就更是什麽都做不到,什麽都不会改变,什麽都不会结束.
  • 相关阅读:
    组合数,错排——HDU-2049
    欧拉函数——POJ-2480
    欧拉函数——HYSBZ
    数论——HYSBZ
    cordova js调用原生
    Backbone js 学习
    最优二叉搜索树 java实现 学习 备忘
    chrome允许加载本地文件
    IOS、Android html5页面输入的表情符号变成了乱码”???“
    创建第一个android应用
  • 原文地址:https://www.cnblogs.com/Sport-river/p/13870813.html
Copyright © 2020-2023  润新知