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\n",ans);
}
return 0;
}
浙公网安备 33010602011771号