• AtCoder Beginner Contest 332


    前面两道阅读理解直接跳过。

    C - T-shirts

    大意

    有两种衬衫,初始时你有a衬衫m件,没有b衬衫。穿过的衬衫必须要等到洗完才能继续穿。

    接下来n天,每天会做三种活动中的一种:

    • 洗衣服,之前穿过的衬衫都可以再穿。
    • 待家里,两种衬衫都能穿。
    • 打比赛,只能穿b衬衫。

    问b衬衫至少买多少件,才能满足这n天的穿着需求。

    思路

    如果待家里,肯定能穿a衬衫就穿a衬衫,不够才买b衬衫。

    记录已经穿了的a衬衫和b衬衫件数,每到洗衣服天就重置使用过的 a衬衫和b衬衫。

    期间b衬衫的最大值即为答案。

    代码

    1. #include
    2. using namespace std;
    3. int main(){
    4. ios::sync_with_stdio(0);
    5. cin.tie(0), cout.tie(0);
    6. int n, m;
    7. string s;
    8. cin >> n >> m >> s;
    9. int p = m, l = 0, b = 0;
    10. for(int i = 0; i < n; i++){
    11. if(s[i] == '0') p = m, l = b;
    12. else if(s[i] == '1'){
    13. if(p > 0) p--;
    14. else if(l > 0) l--;
    15. else b++;
    16. }else{
    17. if(l > 0) l--;
    18. else b++;
    19. }
    20. }
    21. cout << b << endl;
    22. return 0;
    23. }

    D - Swapping Puzzle

    大意

    给定两个矩阵AB,通过下面两个操作,让矩阵A变成矩阵B

    • 交换相邻两行
    • 交换相邻两列

    问最小的操作次数。

    思路

    p_i表示现在的第i行原来的行数,q_i表示现在的第i列原来的列数。

    枚举p,q的全排列,计算p,q的逆序对数量总和(逆序对数量就是交换次数),打擂台去最小值。

    代码

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int INF = 0x3f3f3f3f;
    7. int main(){
    8. ios::sync_with_stdio(0);
    9. cin.tie(0), cout.tie(0);
    10. int h, w;
    11. cin >> h >> w;
    12. vectorint>> a(h, vector<int>(w, 0));
    13. vectorint>> b(h, vector<int>(w, 0));
    14. for(auto &i: a) for(auto &j: i) cin >> j;
    15. for(auto &i: b) for(auto &j: i) cin >> j;
    16. vector<int> p(h), q(w);
    17. iota(p.begin(), p.end(), 0);
    18. iota(q.begin(), q.end(), 0);
    19. auto check = [&]() -> bool{
    20. for(int i = 0; i < h; i++)
    21. for(int j = 0; j < w; j++)
    22. if(a[p[i]][q[j]] != b[i][j]) return false;
    23. return true;
    24. };
    25. int ans = INF;
    26. do{
    27. do{
    28. if(!check()) continue;
    29. int num = 0;
    30. for(int j = 0; j < h; j++)
    31. for(int i = 0; i < j; i++) num += p[i] > p[j];
    32. for(int j = 0; j < w; j++)
    33. for(int i = 0; i < j; i++) num += q[i] > q[j];
    34. ans = min(ans, num);
    35. } while(next_permutation(q.begin(), q.end()));
    36. } while(next_permutation(p.begin(), p.end()));
    37. cout << (ans == INF? -1: ans) << endl;
    38. return 0;
    39. }

    E - Lucky Bag

    大意

    n个物品放到d个袋子中,每个物品有一个重量w_i,放入袋子中后,设每个袋子内物品总重x_i,求这些袋子内物品总重数据x_i 的方差最小值。

    思路

    求方差,只需要最小化平方和。

    数据量很小,考虑状压DP。

    dpi,Sdpi,S表示现在已经分出了i组,且集合SS内的数已经被选走了时的最小的平方和。

    可得:dpi,S=minTS{dpi1,T+(jSTwj)2}

    注意在计算答案之前,都只能使用整数计算,否则会有精度问题。

    代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. #define int long long
    6. typedef long double real;
    7. const int INF = 3e18;
    8. signed main() {
    9. ios::sync_with_stdio(0);
    10. cin.tie(0), cout.tie(0);
    11. int n, d;
    12. cin >> n >> d;
    13. vector<int> w(n), s(1 << n);
    14. vectorint>> f(n + 1, vector<int>(1 << n));
    15. for (int i = 0; i < n; i++) {
    16. cin >> w[i];
    17. for (int j = 0; j < (1 << n); j++)
    18. if (j >> i & 1) s[j] += w[i];
    19. }
    20. for (int i = 0; i < (1 << n); i++) s[i] *= s[i];
    21. for (int i = 1; i < (1 << n); i++) f[0][i] = INF;
    22. for (int i = 1; i <= d; i++)
    23. for (int j = 0; j < (1 << n); j++) {
    24. f[i][j] = s[j];
    25. for (int k = j; k; k = j & k - 1) f[i][j] = min(f[i][j], f[i - 1][k] + s[j ^ k]);
    26. }
    27. real ans = 1.0L * (f[d][(1 << n) - 1] * d - s[(1 << n) - 1]) / (d * d);
    28. cout << fixed << setprecision(15) << ans << endl;
    29. return 0;
    30. }

    F - Random Update Query

    大意

    给定一个序列,执行q次以下操作:

    • 给定l,r,x,等概率地从区间[l,r]挑一个数改为x

    求最后每个元素的期望,对998244353取模。

    思路

    容易发现变的概率是1rl+1,不变的概率是rlrl+1

    因此每个操作就是对所有满足i[l,r]i进行以下修改:

    Ai=rlrl+1Ai+1rl+1x

    维护一棵支持区间加,区间乘,单点查询的线段树即可。每次对区间[l,r]inv(rl+1)×(rl),加上inv(rl+1)x即可。

    代码

    1. #include
    2. #include
    3. using namespace std;
    4. #define int long long
    5. const int P = 998244353;
    6. int qpow(int a, int k){
    7. int res = 1;
    8. while (k){
    9. if (k & 1) res = res * a % P;
    10. a = a * a % P;
    11. k >>= 1;
    12. }
    13. return res;
    14. }
    15. int inv(int x){
    16. return qpow(x, P - 2);
    17. }
    18. struct segment{
    19. struct Node{
    20. int l = 0, r = 0, add = 0, mul = 0, sum = 0;
    21. };
    22. vector tr;
    23. segment(vector<int> &a){
    24. int n = a.size();
    25. tr.resize(n << 2);
    26. build(1, 1, n, a);
    27. }
    28. void pushdown(int u){
    29. int len1 = tr[u << 1].r - tr[u << 1].l + 1;
    30. int len2 = tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1;
    31. tr[u << 1].sum = ((tr[u << 1].sum * tr[u].mul) % P + (tr[u].add * len1) % P)% P;
    32. tr[u << 1 | 1].sum = ((tr[u << 1 | 1].sum * tr[u].mul) % P + (tr[u].add * len2) % P) % P;
    33. tr[u << 1].mul = (tr[u << 1].mul * tr[u].mul) % P;
    34. tr[u << 1 | 1].mul = (tr[u << 1 | 1].mul * tr[u].mul) % P;
    35. tr[u << 1].add = ((tr[u << 1].add * tr[u].mul) % P + tr[u].add) % P;
    36. tr[u << 1 | 1].add = ((tr[u << 1 | 1].add * tr[u].mul) % P + tr[u].add) % P;
    37. tr[u].add = 0;
    38. tr[u].mul = 1;
    39. }
    40. void pushup(int u){
    41. tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % P;
    42. }
    43. void build(int u, int l, int r, vector<int> &a){
    44. tr[u].l = l, tr[u].r = r, tr[u].mul = 1;
    45. if(l == r) tr[u].sum = a[l - 1] % P;
    46. else{
    47. int mid = l + r >> 1;
    48. build(u << 1, l, mid, a), build(u << 1 | 1, mid + 1, r, a);
    49. pushup(u);
    50. }
    51. }
    52. int query(int u, int i){
    53. if(tr[u].l == i && tr[u].r == i) return tr[u].sum % P;
    54. pushdown(u);
    55. int mid = tr[u].l + tr[u].r >> 1;
    56. if(i <= mid) return query(u << 1, i);
    57. else return query(u << 1 | 1, i);
    58. }
    59. void modify(int u, int l, int r, int v, bool f){
    60. if(tr[u].l == l && tr[u].r == r){
    61. if(!f){
    62. tr[u].sum = (tr[u].sum + v * (tr[u].r - tr[u].l + 1)) % P;
    63. tr[u].add = (tr[u].add + v) % P;
    64. }
    65. else{
    66. tr[u].sum = (tr[u].sum * v) % P;
    67. tr[u].mul = (tr[u].mul * v) % P;
    68. tr[u].add = (tr[u].add * v) % P;
    69. }
    70. return;
    71. }
    72. pushdown(u);
    73. int mid = tr[u].l + tr[u].r >> 1;
    74. if(r <= mid) modify(u << 1, l, r, v, f);
    75. else if(l > mid) modify(u << 1 | 1, l, r, v, f);
    76. else{
    77. modify(u << 1, l, mid, v, f);
    78. modify(u << 1 | 1, mid + 1, r, v, f);
    79. }
    80. pushup(u);
    81. }
    82. };
    83. signed main(){
    84. ios::sync_with_stdio(0);
    85. cin.tie(0), cout.tie(0);
    86. int n, q;
    87. cin >> n >> q;
    88. vector<int> a(n);
    89. for(auto &i: a) cin >> i;
    90. segment seg(a);
    91. while(q--){
    92. int l, r, z;
    93. cin >> l >> r >> z;
    94. int len = r - l + 1;
    95. seg.modify(1, l, r, (inv(len) * (len - 1)) % P, true);
    96. seg.modify(1, l, r, (inv(len) * z) % P, false);
    97. }
    98. for(int i = 1; i <= n; i++) cout << seg.query(1, i) << ' ';
    99. cout << endl;
    100. return 0;
    101. }

  • 相关阅读:
    基于SpringMVC+Hibernate开发企业库存管理系统的设计与实现+任务书+PPT 毕业设计
    引擎入门 | Unity UI简介–第2部分(5)
    改进YOLOv7 | 头部解耦 | 将YOLOX解耦头添加到YOLOv7 | 涨点杀器
    DO280管理应用部署--pod调度控制
    Spring依赖注入源码解析(上)
    多线程之ThreadPoolExecutor
    加强版python连接飞书通知——本地电脑PC端通过网页链接打开本地已安装软件(调用注册表形式,以漏洞扫描工具AppScan为例)
    堆 AcWing 838. 堆排序
    STM32 invalid UTF-8 in comment 警告解决办法
    MySQL5.7版本在CentOS系统安装
  • 原文地址:https://blog.csdn.net/sblsf/article/details/138169419