码迷,mamicode.com
首页 > 其他好文 > 详细

Number Of Permutations

时间:2019-08-23 21:59:49      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:names   force   flag   define   col   ret   point   mod   code   

题目链接

题意:给你n个坐标,求组成序列的总数,其中x,y都不能升序。

思路:刚开始就想到了思路,但情况没有特判对。因为总共的序列有n!种,因为xy都不能升序,所以先给x,y分别排序,例如给x排升序,x里面的每一组重复的数的排列就是对于x来说不符合情况的种数,就应该减去每个重复的x个数的阶乘之积。y也是如此,但是你减去了可能重复的情况,那就是x,y都升序,且重复。所以还要加上这种情况算出来的种数。首先要特判一下有没有这种情况。代码上注释很清楚,上代码。

#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
const int mod=998244353;
int n,i,j,m;
ll ans,p[300005],s;
struct point
{
    int x;
    int y;
}a[300005];
bool cmp(point a,point b)
{
    if(a.x==b.x)
        return a.y<b.y;
    return a.x<b.x;
}
bool cmp2(point a,point b)
{
    return a.y<b.y;
}
int main()
{
    scanf("%d",&n);
    p[0]=1;
    for(i=1;i<=n;i++)
    {
        scanf("%d %d",&a[i].x,&a[i].y);
        p[i]=p[i-1]*i%mod;
    }
    ans=p[n];
    sort(a+1,a+1+n,cmp);
    int flag=0;
    for(i=2;i<=n;i++)
        if(!(a[i].x>=a[i-1].x&&a[i].y>=a[i-1].y))
            flag=1;//判断有没有重复减的情况。 
    if(!flag)
    {
        //加上重复减的情况 。 
        s=1;
        for(i=1;i<=n;)
        {
            for(j=i;j<=n&&a[i].x==a[j].x&&a[i].y==a[j].y;j++);
            s=s*p[j-i]%mod;
            i=j;
        }
        ans+=s;
    }
    s=1;
    //减去光按a[i].x的情况。 
    for(i=1;i<=n;)
    {
        for(j=i;j<=n&&a[i].x==a[j].x;j++);
        s=s*p[j-i]%mod;
        i=j;
    }
    ans-=s;
    sort(a+1,a+1+n,cmp2);
    s=1;
    //减去光按a[i].y的情况。 
    for(i=1;i<=n;)
    {
        for(j=i;j<=n&&a[i].y==a[j].y;j++);
        s=s*p[j-i]%mod;
        i=j;
    }
    ans-=s;
    printf("%lld\n",((ans%mod)+mod)%mod);//防止负数。
}

 

Number Of Permutations

标签:names   force   flag   define   col   ret   point   mod   code   

原文地址:https://www.cnblogs.com/2462478392Lee/p/11402790.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!