• Codeforces.487C.Prefix Product Sequence(构造)


    题目链接


    (Description)

    对于一个序列(a_i),定义其前缀积序列为(a_1 mathbb{mod} n, (a_1a_2) mathbb{mod} n,...,(a_1a_2...a_n) mathbb{mod} n)
    给定(n),求一个(n)的排列,使得该排列的前缀积序列是([0,1,2,...,n-1])的一个排列。无解输出(NO)
    (nleq10^5)

    (Solution)

    考虑无解的情况。因为(n!equiv0 (mathbb{mod} n)),所以((n-1) otequiv0 (mathbb{mod} n))
    (n)为质数显然可以满足。否则设(n=pq)
    (p eq q),那么有((n-1)!equiv0 (mathbb{mod} n)),GG了。
    (p=q),当(n>4)时,(2p<n),所以也有((n-1)!equiv0 (mathbb{mod} n)),GG。
    所以(n)为大于(4)的合数时无解。特判一下(n=4)

    首先(a_1)要填(1)(a_n)要填(n)
    考虑能不能直接让前缀积序列变成(1,2,...,0)。那么(a_i=frac{i}{i-1} mathbb{mod} n, i>1)
    只需要判断是否有(frac{a}{a-1}=frac{b}{b-1}, 1lt a eq blt n)
    稍微化一下,(frac{a}{a-1}=1+frac1a, frac{b}{b-1}=1+frac1b),而我们知道每个数的逆元是唯一的,所以这么做就OK啦。


    //46ms	600KB
    #include <cstdio>
    #include <algorithm>
    typedef long long LL;
    const int N=1e5+5;
    
    int A[N],inv[N];
    
    bool IsPrime(int x)
    {
    	int t=0;
    	for(int i=2; x!=1; ++i)
    		while(!(x%i))
    		{
    			x/=i;
    			if(++t>1) return 0;
    		}
    	return 1;
    }
    
    int main()
    {
    	int n; scanf("%d",&n);
    	if(n==4) return printf("YES
    1
    3
    2
    4
    "),0;
    	if(!IsPrime(n)) return puts("NO"),0;
    	A[1]=1, A[n]=n, inv[1]=1;
    	for(int i=2; i<n; ++i) inv[i]=1ll*(n-n/i)*inv[n%i]%n, A[i]=1ll*i*inv[i-1]%n;
    	puts("YES");
    	for(int i=1; i<=n; ++i) printf("%d
    ",A[i]);
    
    	return 0;
    }
    
  • 相关阅读:
    作业7-英文词频统计预备,组合数据类型练习
    作业6-凯撒编码、GDP格式化输出、九九乘法表
    作业5-字符串操作
    作业3-turtle库基础练习
    作业2-Python基础练习
    理解管理信息系统
    Git-git rebase详解
    C语言中基本的数据类型
    读取配置文件的C语言接口实现
    Linux之异步IO机制分析
  • 原文地址:https://www.cnblogs.com/SovietPower/p/10518469.html
Copyright © 2020-2023  润新知