zoukankan      html  css  js  c++  java
  • gmoj 6832. 2020.10.24【NOIP提高A组】T2.world

    (Solution)

    发现只需要考虑(1)走了(n)步以后是否首次回到(1)即可。
    搞了半天发现还可以看看(1)走了(n/2)步后是否首次到达(n)
    然后(GG)
    正解发现可以倒推。
    考虑奇数情况,设(t=(n+x+1)/2),那么((t*2)%(n+1)=x)
    偶数情况显然也可以。
    所以题目就可以转换成了(2^n≡1(mod (n+1)))

    (Solution 1)
    可以尝试打表。对于每一个(n),如果它合法,需要满足
    (2^n≡1(mod (n+1)))且不存在(2^p≡1(mod (n+1)))其中(p)最小且(p<n)
    考虑这里的(p)
    (1.)(p<n)(pmid n)
    假设存在(2^p≡1(mod (n+1)))其中(p<n)
    (2p)(3p)(4p)。。。都符合上面的式子。
    (p*d=n),我们可以枚举(d)来判断(p/d)是否存在即可。
    这样可以考虑到所有的(p)
    (2.)(p<n)(p mid n)
    可以证明这种情况是不存在的。
    (2^n=2^{lfloor n/p floor *p+nmod p})
    由于(2^n≡1)(2^p≡1)
    所以可以化简得到:
    (1=2^{nmod p}),这样的话与(p)最小相矛盾了。
    或者说只有当(nmod p=0)时是(p)最小且满足的

    所以我们只需要枚举(n)的质因子然后判断一下即可。
    这里可以暴力,也可以这样,但是“这样”会(TLE)(原因不知)

    这样可以(100000)个地打表即可。

    (Solution 2)
    对于(2^n≡1(mod (n+1)))
    发现(n+1)一定是一个质数。
    (n+1)不是质数,则由欧拉定理得
    (2^{phi(n+1)}≡1(mod (n+1)))
    由于(phi(n+1)<n),从(Solution 1)中的规律可得不合法。
    所以我们需要枚举(n)的质因子,然后判断(n-1)是否可以即可。
    判断方法为(Solution 1)的方法。

    (Code)

    #include <cstdio>
    #define N 700010
    #define db double
    #define ll long long
    #define mem(x, a) memset(x, a, sizeof x)
    #define mpy(x, y) memcpy(x, y, sizeof y)
    #define fo(x, a, b) for (int x = (a); x <= (b); x++)
    #define fd(x, a, b) for (int x = (a); x >= (b); x--)
    #define go(x) for (int p = tail[x], v; p; p = e[p].fr)
    using namespace std;
    int n, pri[N], tot = 0;
    bool label[10000010];
    ll ans = 0;
    
    void prepare() {
    	fo(i, 2, n) {
    		if (! label[i]) pri[++tot] = i;
    		fo(j, 1, tot) {
    			if (i * pri[j] > n) break;
    			label[i * pri[j]] = 1;
    			if (i % pri[j] == 0) break;
    		}
    	}
    }
    
    ll ksm(ll x, int y, int mo) {
    	ll s = 1;
    	while (y) {
    		if (y & 1) s = s * x % mo;
    		x = x * x % mo, y >>= 1;
    	}
    	return s;
    }
    
    bool check(int val) {
    	int yuan_ = val;
    	fo(i, 1, tot) {
    		if (pri[i] * pri[i] > val) break;
    		if (val % pri[i] == 0) {
    			if (ksm(2, yuan_ / pri[i], yuan_ + 1) == 1) return 0;
    			while (val % pri[i] == 0) val /= pri[i];
    		}
    	}
    	if (val > 1 && ksm(2, yuan_ / val, yuan_ + 1) == 1) return 0;
    	return 1;
    }
    
    int main()
    {
    	freopen("world.in", "r", stdin);
    	freopen("world.out", "w", stdout);
    	scanf("%d", &n);
    	prepare();
    	fo(i, 2, tot) {
    		int val = pri[i] - 1;
    		if (ksm(2, val, val + 1) != 1) continue;
    		if (check(val)) ans = ans + val;
    	}
    	printf("%.5lf
    ", (db)ans / (n / 2));
    	return 0;
    }
    
  • 相关阅读:
    element ui 表单清空
    element ui 覆盖样式 方法
    element ui 修改表单值 提交无效
    element ui 抽屉里的表单输入框无法修改值
    element ui 抽屉首次显示 闪烁
    css 左侧高度 跟随右侧内容高度 自适应
    PICNUF框架
    elementui 抽屉组件标题 出现黑色边框
    vue 子组件跨多层调用父组件中方法
    vue 编辑table 数据 未点击提交,table里的数据就发生了改变(深拷贝处理)
  • 原文地址:https://www.cnblogs.com/jz929/p/13869693.html
Copyright © 2011-2022 走看看