codeforces1027D Number Of Permutations(容斥)

曾经终败给现在 2024-04-17 05:49 164阅读 0赞

题意:n个二维数对(ai,bi),求将n个数对排列之后,ai,bi都不是单调不减的。这样的排列有多少个。

分析:简单容斥。答案为总的排列数-(ai单调不减或者bi单调不减的排列数)+(ai,bi都单调不减的排列数)。ai单调不减或者bi单调不减的方案分别排序记录相邻位置相同树的个数就行。考虑如何计算ai、bi都单调不减的排列数。我们就在按a排序的基础上在按b排序,注意要判断整个序列是否满足b不降(因为这个wa了),如果满足,则去每一段相同的a中找b相同连续段。

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. const int N = 1e6+5;
  5. const ll mod = 998244353;
  6. ll n,f[N];
  7. struct nd {
  8. int l,r;
  9. }p[N];
  10. bool cmp(nd a,nd b) {
  11. return a.r<b.r;
  12. }
  13. bool cmp2(nd a,nd b) {
  14. if(a.l==b.l) return a.r<b.r;
  15. return a.l<b.l;
  16. }
  17. int main() {
  18. f[1]=1;
  19. for(int i=2;i<N;i++) f[i]=f[i-1]*i%mod;
  20. cin>>n;
  21. for(int i=1;i<=n;i++)
  22. cin>>p[i].l>>p[i].r;
  23. sort(p+1,p+1+n,cmp);
  24. ll s1=1,s2=1,cnt=1;
  25. for(int i=2;i<=n;i++) {
  26. if(p[i].r==p[i-1].r) cnt++;
  27. else (s1*=f[cnt])%=mod,cnt=1;
  28. }
  29. (s1*=f[cnt])%=mod;
  30. cnt=1;
  31. sort(p+1,p+1+n,cmp2);
  32. for(int i=2;i<=n;i++) {
  33. if(p[i].l==p[i-1].l) cnt++;
  34. else (s2*=f[cnt])%=mod,cnt=1;
  35. }
  36. (s2*=f[cnt])%=mod;
  37. cnt=1;
  38. int fg=0;
  39. for(int i=2;i<=n;i++)
  40. if(p[i].r<p[i-1].r) fg=1;
  41. if(fg) cout<<(f[n]-s1-s2+2*mod)%mod<<endl;
  42. else {
  43. ll s3=1;
  44. for(int i=2;i<=n;i++) {
  45. if((p[i].l==p[i-1].l)&&(p[i].r==p[i-1].r)) cnt++;
  46. else (s3*=f[cnt])%=mod,cnt=1;
  47. }
  48. (s3*=f[cnt])%=mod;
  49. cout<<(f[n]-s1+mod-s2+mod+s3)%mod<<endl;
  50. }
  51. return 0;
  52. }

发表评论

表情:
评论列表 (有 0 条评论,164人围观)

还没有评论,来说两句吧...

相关阅读

    相关 原理详解

    翻译:vici@cust 对容斥原理的描述 容斥原理是一种重要的组合数学方法,可以让你求解任意大小的集合,或者计算复合事件的概率。 描述        容斥原理