permutaion - 结论题

题目大意:给定n和某个二元运算F(x,y)=(x+y)%n或F(x,y)=xy%n或F(x,y)=x^y%n,问是否存在三个0到n-1的排列A,B,C,使得F(Ai,Bi)=Ci。0^0没有定义。
1e5组数据,n<=1e14,但是n>2e7的只有不超过6组。
题解:
结论是若F(x,y)=x+y那么只有n是奇数的时候有解。显然构造Ai=Bi=i即可,无解亦易证。
否则若F(x,y)=xy那么只有1<=n<=2时有解。(打表看出来的(雾
否则若F(x,y)=x^y,则只有n<4或者n=2p(p是质数)并且|mu(p)|=1,其实mu是莫比乌斯函数。至于为啥就不知道了。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define gc getchar()
#define lint long long
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
#define N 20000001
using namespace std;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
inline lint inln()
{
    lint x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
int p[N],c;bool np[N],mu[N];
inline int is_prime(lint n) { for(int i=1;i<=c&&p[i]<=n/p[i];i++) if(n%p[i]==0) return 0;return 1; }
inline int all_one(lint n) { for(int i=1;i<=c&&p[i]<=n/p[i];i++) if(n%p[i]==0) { n/=p[i];if(n%p[i]==0) return 0; }return 1; }
inline int prelude(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!np[i]) p[++c]=i,mu[i]=1;
        for(int j=1;j<=c&&p[j]<=n/i;j++)
        {
            int x=p[j]*i;np[x]=1;
            if(i%p[j]) mu[x]=mu[i];
            else { mu[x]=0;break; }
        }
    }
    return 0;
}
int main()
{
    for(int T=inn()+prelude(N-1);T;T--)
    {
        int k=inn();lint n=inln(),p=n/2;
        if(k==1) { printf("%s\n",(n&1ll)?"YES":"NO");continue; }
        if(k==2) { printf("%s\n",(n<=2)?"YES":"NO");continue; }
        if(n<=3) { printf("%s\n",(n>=2)?"YES":"NO");continue; }
        if(n&1ll) { printf("NO\n");continue; }
        if(n<N&&!np[n]&&mu[n])  printf("YES\n");
        else if(is_prime(p)&&all_one(p-1)) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/82352568