[关闭]
@2368860385 2020-11-07T03:05:22.000000Z 字数 1921 阅读 335

day6

正睿提高


LZZ出的题!

T1 Tiny Counting

这里你需要解决一道微型计数题——关于人畜无害的四元组。
给定长度为 的数组 ,下标为 ,你需要统计有多少个四元组 满足:,且 互不相等。

容斥一下,首先求出所有,和的对数,两两组合,相乘。然后考虑去有相同数的情况。
一共四种情况:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<cctype>
  7. #include<set>
  8. #include<vector>
  9. #include<queue>
  10. #include<map>
  11. #define fi(s) freopen(s,"r",stdin);
  12. #define fo(s) freopen(s,"w",stdout);
  13. using namespace std;
  14. typedef long long LL;
  15. inline int read() {
  16. int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
  17. for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
  18. }
  19. const int N = 200005;
  20. struct BIT{
  21. int sum[N], n;
  22. void Clear() {
  23. memset(sum, 0, sizeof(sum));
  24. }
  25. void update(int p,int v) {
  26. for (; p<=n; p+=(p&(-p))) sum[p] += v;
  27. }
  28. int query(int p) {
  29. int res = 0;
  30. for (; p; p-=(p&(-p))) res += sum[p];
  31. return res;
  32. }
  33. int Ask(int l,int r) {
  34. return query(r) - query(l - 1);
  35. }
  36. }bit;
  37. int a[N], b[N], Lx[N], Ld[N], Rx[N], Rd[N];
  38. int main() {
  39. int n = read();
  40. bit.n = n;
  41. for (int i=1; i<=n; ++i) a[i] = read(), b[i] = a[i];
  42. sort(b + 1, b + n + 1);
  43. int cnt = 1;
  44. for (int i=2; i<=n; ++i) if (b[i] != b[cnt]) b[++cnt] = b[i];
  45. for (int i=1; i<=n; ++i) a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b;
  46. for (int i=1; i<=n; ++i) {
  47. Lx[i] = bit.Ask(1, a[i] - 1);
  48. Ld[i] = bit.Ask(a[i] + 1, n);
  49. bit.update(a[i], 1);
  50. }
  51. bit.Clear();
  52. for (int i=n; i>=1; --i) {
  53. Rx[i] = bit.Ask(1, a[i] - 1);
  54. Rd[i] = bit.Ask(a[i] + 1, n);
  55. bit.update(a[i], 1);
  56. }
  57. // for (int i=1; i<=n; ++i) cout << Lx[i] << " "; puts("");
  58. // for (int i=1; i<=n; ++i) cout << Ld[i] << " "; puts("");
  59. // for (int i=1; i<=n; ++i) cout << Rx[i] << " "; puts("");
  60. // for (int i=1; i<=n; ++i) cout << Rd[i] << " "; puts("");
  61. LL ans = 0, ans1 = 0, ans2 = 0, ans3 = 0, ans4 = 0;
  62. for (int i=1; i<=n; ++i)
  63. ans1 += Rd[i], ans2 += Rx[i];
  64. ans = ans1 * ans2;
  65. ans1 = 0, ans2 = 0;
  66. for (int i=1; i<=n; ++i) {
  67. ans1 += (1ll * Lx[i] * Rx[i]);
  68. ans2 += (1ll * Ld[i] * Rd[i]);
  69. ans3 += (1ll * Lx[i] * Ld[i]);
  70. ans4 += (1ll * Rx[i] * Rd[i]);
  71. }
  72. ans = ans - ans1 - ans2 - ans3 - ans4;
  73. cout << ans;
  74. return 0;
  75. }

T2 Medium Counting

这里你需要解决一道中型计数题——关于捉摸不定的字典序。
个字符串,分别记为 ,它们由小写字母和 组成,你需要给每个 都填上一个小写字母。
你需要统计,有多少种不同的给 填上字母的方法,使得对于每个 的字典序严格小于 的字典序。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注