CF Number Of Permutations 容斥原理

题目链接:https://www.luogu.org/problem/CF1207D

题意:给你一个二维序列,如果两维中任一维从1-n满足单调不减,则是坏序列,否则是好序列,求问使的其是好序列的排序有多少种

分析:可以先单调排第一维和第二维求得总数,分别为c1,c2,再排同时满足第一维和第二维单调不减的,记为c3

故答案为:n!(总数)-(c1+c2-c3)(坏序列个数)

这种设计到取模乘之后再减的也是可以直接来进行处理的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+7;
const int inf=0x3f3f3f3f;
const int N=1e7;
const ll mod=998244353;
#define meminf(a) memset(a,0x3f,sizeof(a))
#define mem0(a) memset(a,0,sizeof(a))
struct node{
    int x,y;
}a[maxn];
bool cmp1(node a,node &b) {
    return a.x<b.x;
}
bool cmp2(const node &a,const node &b) {
    return a.y<b.y;
}
bool cmp3(const node &a,const node &b){
    return a.x==b.x?a.y<b.y:a.x<b.x;
} 
int main(){
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
    sort(a+1,a+1+n,cmp1);
    ll fx=1,k;
    //fx记录第一维单调不减的数量 
    for(int i=1;i<=n;i++){
        if(a[i].x==a[i-1].x)k++;
        else k=1;
        fx=(fx*k)%mod; 
    }
    sort(a+1,a+1+n,cmp2);
    ll fy=1;
    for(int i=1;i<=n;i++){
        if(a[i].y==a[i-1].y)k++;
        else k=1;
        fy=(fy*k)%mod; 
    }
    sort(a+1,a+1+n,cmp3);
    ll f=1;
    for(int i=1;i<=n;i++){
        if(a[i].y<a[i-1].y){
            f=0;
            break;
        }
    }
    if(f){
        for(int i=1;i<=n;i++){
            if(a[i].y==a[i-1].y&&a[i].x==a[i-1].x) k++;
            else k=1;
            f=(f*k)%mod;
        }
    }
    ll res=(fx+fy-f+mod)%mod;
    ll res2=1;
    for(int i=1;i<=n;i++) res2=(res2*i)%mod;
    printf("%lld\n",(res2-res+mod)%mod);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qingjiuling/p/11423923.html