codeforces 698F 数学

本文介绍了一种构造特定排列的方法,使得排列中的元素满足特定的质因数条件。通过质因数分解、计数和置换操作,算法能够解决已知部分元素情况下的排列问题,并通过阶乘统计给出可行排列的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:构造一个1到n的排列a1,a2,......an 满足对于任意i,j满足1<=i<j<=n ai,aj 互质当且仅当i,j互质。a中一些元素已知,求可以构造的排列个数。

对于两个质数p1,p2,如果有这两个质数因子的数的个数相等(既n/p1=n/p2)那么可以将所有数的质因子中出现的这两个质数交换。

如果两个数包含相同的质因子,那么可以将两个数交换。

如果第i个数ai已知:
如果ai质因子个数和i的质因子个数不等,无解。
如果ai的第j个质因子和i的第j个质因子出现次数不等,无解。
注意设ai有pi个质因子,这里只需要判断前pi-1个质因子是否相等和第pi个质因子出现次数是否相等即可。因为前pi-1个质因子小于根号n,对于小于根号n的两个质数p1,p2:n/p1和n/p2不等。
如果最后一个质因子已经有对应的质因子,无解。

最后阶乘统计答案即可。

注意处理1的问题。

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define ll long long
#define N 1100000
int n;
ll jc[N],ans;
int a[N],num[N],num1[N],pos[N],mul[N];
int pre[N],nex[N];
vector<int>v[N];
void quit(){puts("0");exit(0);}
int main()
{
    //freopen("tt.in","r",stdin);
    scanf("%d",&n);
    jc[0]=1;
    for(int i=1;i<=n;i++)jc[i]=jc[i-1]*i%mod;
    for(int i=1;i<=n;i++)mul[i]=1;
    for(int i=2,pre=0;i<=n;i++)
        if(!v[i].size())
        {
            num[n/i]++;pos[i]=n/i;
            for(int j=i;j<=n;j+=i)
                v[j].push_back(i),mul[j]*=i;
        }
    for(int i=1;i<=n;i++)num1[mul[i]]++;
    num[1]++;pos[1]=1;
    v[1].push_back(1);

    for(int i=1,x,y;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]==0)continue;
        num1[mul[a[i]]]--;
        if(v[a[i]].size()!=v[i].size())quit();
        for(int j=0;j<v[i].size()-1;j++)
            if(v[a[i]][j]!=v[i][j])quit();
        x=v[a[i]].back();y=v[i].back();
        if(pos[x]!=pos[y])quit();
        if(pre[x]&&pre[x]!=y)quit();
        if(nex[y]&&nex[y]!=x)quit();
        if(!pre[x]&&!nex[y])num[pos[x]]--;
        pre[x]=y;nex[y]=x;
    }
    ans=1;
    for(int i=1;i<=n;i++)ans=ans*jc[num1[i]]%mod;
    for(int i=1;i<=n;i++)ans=ans*jc[num[i]]%mod;
    printf("%I64d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值