• CF 1027D Number Of Permutations


    题意:给你两个给你一个n对整数的序列:(a1,b1),(a2,b2),…,(an,bn)。如果按第一个元素的非降序排序,

              或者按第二个元素的非降序排序,则此序列称为坏序列。否则顺序是好的。输出有多少种排列方式使得这序列是好的。

    思路:可以先求出坏序列有多少种,再用n!减去坏序列的种数即可,由于只要a,b其中一个为坏序列该序列就为坏序列,所以

               坏序列的种数就等于a为坏序列的种数+b为坏序列的种数-a,b同时为坏序列的种数。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    using namespace std;
    #define ll long long
    ll inf=998244353;
    struct node
    {
        ll x;
        ll y;
    }a[300005];
    bool cmp(node xx,node yy)
    {
        if(xx.x==yy.x)
            return xx.y<yy.y;
        return xx.x<yy.x;
    }
    ll b[300005],c[300005];
    ll fun(ll n)
    {
        ll s=1;
        for(ll i=2;i<=n;i++)
            s=(s*i)%inf;
        return s%inf;
    }
    int main()
    {
        ll n;
        while(~scanf("%lld",&n))
        {
            for(ll i=1;i<=n;i++)
            {
                scanf("%lld %lld",&a[i].x,&a[i].y);
                b[i]=a[i].x;
                c[i]=a[i].y;
            }
            sort(b+1,b+n+1);
            sort(c+1,c+n+1);
            ll ans=1,sum=1,sum1=1,sum2=1;
            ll s=1,s1=1;
            for(ll i=2;i<=n;i++)
            {
                if(b[i]==b[i-1])
                    s++;
                else
                {
                    sum=(sum*fun(s))%inf;
                    s=1;
                }
                if(c[i]==c[i-1])
                    s1++;
                else
                {
                    sum1=(sum1*fun(s1))%inf;
                    s1=1;
                }
            }
            if(b[n]==b[n-1])
                sum=(sum*fun(s))%inf;
            if(c[n]==c[n-1])
                sum1=(sum1*fun(s1))%inf;
            sort(a+1,a+n+1,cmp);
            s=1;
            int v=1;
            for(ll i=2;i<=n;i++)
            {
                if(a[i].x==a[i-1].x&&a[i].y==a[i-1].y)
                    s++;
                else
                {
                    sum2=(sum2*fun(s))%inf;
                    s=1;
                }
                if(a[i].y<a[i-1].y)
                {
                    v=0;
                    break;
                }
            }
            if(a[n].x==a[n-1].x&&a[n].y==a[n-1].y)
                sum2=(sum2*fun(s))%inf;
            if(v==0)
                sum2=0;
            sum=(sum1+sum+inf-sum2)%inf;
            ans=fun(n);
            ans=(ans+inf-sum)%inf;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    P2569 [SCOI2010]股票交易
    P1963 [NOI2009]变换序列
    My thoughts after NOIP 2018(2)
    洛谷 P3159(BZOJ 2668)[CQOI2012]交换棋子
    My thoughts after NOIP 2018(1)
    洛谷【P1523】旅行商的背包(算法导论 15-1) 题解
    洛谷【P2458】[SDOI2006]保安站岗 题解 树上DP
    【BLUESKY的NOIp模拟赛】解题报告
    bzoj4400
    luogu2034
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/11403701.html
Copyright © 2020-2023  润新知