Educational Codeforces Round 71 Editorial D
是一道permutation的题目。
观察发现一共最多有N!种排列方式,对于第一关键字,如果有相同的元素a1,a2...那么bad permutation C1=a1*a2*...对于第二关键字相同,求出C2。但是如果总的减去两种bad permutation 显然不正确,因为有可能删除了重复的排列,那么就把这个重复的再加上就好了,就是第一关键字有序,第二关键字也有序。最后的ans=N!-C1-C2+C3.
自己写的应该是在取模的时候炸了,然后发现了一个非常优秀的写法。供参考
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=3e5+5; 5 const ll mod=998244353; 6 7 pair <int,int > a[maxn]; 8 ll d[maxn]; 9 ll fi[maxn],se[maxn]; 10 map<pair<int,int>,int> M; 11 int n; 12 ll sum=1;ll e=1,b=1,c=1; 13 int main(){ 14 cin>>n; 15 d[0]=1; 16 for(int i=1;i<=n;i++){ 17 cin>>a[i].first>>a[i].second; 18 d[i]=(d[i-1]*i)%mod; 19 e=e*(++fi[a[i].first])%mod; 20 b=b*(++se[a[i].second])%mod; 21 c=c*(++M[a[i]])%mod; 22 } 23 sort(a+1,a+n+1); 24 25 int now=a[1].second;int sign=1; 26 for(int i=2;i<=n;i++){ 27 if(a[i].second>=now) now=a[i].second; 28 else 29 { 30 sign=0; 31 break; 32 } 33 } 34 ll ans; 35 if(sign) 36 { 37 ans=(d[n]+c+2*mod-e-b)%mod; 38 } 39 else ans=(d[n]+2*mod-e-b)%mod; 40 cout <<ans<<"\n"; 41 42 43 return 0; 44 }