• #约数#洛谷 4296 [AHOI2007]密码箱


    题目

    给定(n(nleq 2*10^9)),求

    [sum_{x=1}^n[x^2mod n==1] ]


    分析

    首先当(n=1)的时候需要特判,
    否则1和(n-1)一定是答案,
    那么对于一个(x=x'+1)来说,也满足
    ((x'+1)^2mod n==1)
    把这个式子拆开可以得到
    (x'(x'+2)mod n==0)
    那么考虑枚举(n)(geqsqrt{n})的约数,
    那么(x')或者(x'+2)一定是这个数的倍数,
    再枚举这个约数的倍数判断是否满足上式即可,
    再通过(x')就可以推出(x)
    PS:为什么不直接枚举(n)的约数?
    因为(<sqrt{n})的约数所对应的另一个数也就是(>sqrt{n})的约数
    当枚举(geqsqrt{n})的约数的倍数,
    如果满足上式也就说明
    (x',x'+2)的另一个数就是(leqsqrt{n})的约数的倍数
    而枚举(leqsqrt{n})的倍数显然会T飞,
    那还不如只枚举(geqsqrt{n})的约数的倍数,
    时间复杂度不会证,也许是(O(sqrt{n}log{n}))


    代码

    #include <cstdio>
    #include <algorithm>
    #define rr register
    using namespace std;
    int n,m,a[100011];
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    signed main(){
    	scanf("%d",&n),a[1]=1,a[m=2]=n-1;
    	if (n==1) return !printf("None");
    	for (rr int i=2;i*i<=n;++i)
    	if (n%i==0){
    		for (rr int j=n/i;j<n;j+=n/i){
    		    if (1ll*j*(j+2)%n==0) a[++m]=j+1;
    		    if (1ll*j*(j-2)%n==0) a[++m]=j-1;
    		}
    	}
    	sort(a+1,a+1+m),m=unique(a+1,a+1+m)-a-1;
    	for (rr int i=1;i<=m;++i) print(a[i]),putchar(10);
    	return 0;
    }
    
  • 相关阅读:
    第三次jsp作业
    快速排列 使用链表
    Cross
    题目
    ranch
    robot
    Mold
    Mold2
    OX_pattern
    KSC sort
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13819732.html
Copyright © 2020-2023  润新知