zoukankan      html  css  js  c++  java
  • Codeforces Round #368 (Div. 2)

    5/5

    失踪多天发一下CF的题解,突然发现CF题解评论区一堆大神在晒解法,我等渣渣就顺手膜拜了一发,学了不少姿势,以后一打完CF就去评论区找姿势好了。。。。。。

    最近有一个感悟,就是不要让别人告诉你一道题的完整思路比较好,最后是懂得大致的解法,自己将所有实现细节都推导一遍,然后再看别人是怎么实现的,这样学到的更多,以前我都是看别人思路看别人的代码,然后发现自己的代码和别人的好像长得一样,原来我顺手把别人的代码copy到脑海中,这样印象不是很深刻,要自己推导实现一遍,然后在学习别人的代码和思路比较好。

     

    题A A. Brain's Photos

    题意:G、B、W输出“#Black&White”,否则输出“#Color”

    题解:略

     

    题B B. Bakery

    题意:告诉你k个地方不能开面包店,然后剩下n-k个地方里面开,然后k个地方买面粉,问你有没有离卖面粉最短的距离开面包店。

    题解:遍历卖面粉的,然后找一个非卖面粉的最短的即可,不行就输出-1。

     

    题C C. Pythagorean Triples

    题意:给你n,构造一个勾股数。

    题解:另k^2 = n^2 + r^2 -> (k - r) * (k + r) = n ^ 2; 

    (1)n<=2,无解

    (2)n为偶数

    k - r = 2;

    k + r = n ^ 2 / 2;

    解得k = n ^ 2 / 4 + 1, r = n ^ 2 / 4 - 1;

    (3)n为奇数

    k - r = 1;

    k + r = n ^ 2;

    解得k = (n ^ 2 + 1) / 2, r = (n ^ 2 - 1) / 2;

     

    题D D. Persistent Bookcase

    题意:给你一个n * m的书架,有四种操作:

    (1)1 i j,在(i,j)上放一本书;

    (2)2 i j,拿掉(i,j)上的一本书;

    (3)3 i,将第i行置反

    (4)4 k,回到第k个操作

    题解:有两种解法(还有一种主席树,本弱不太会):

    (1)dfs离线,op = {1, 2, 3},i-1操作向i操作连边,op = {4},k操作向i操作连边,然后做操作即可,记得变回去。

     

     1 /*zhen hao*/
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 
     5 #define lson l, m, rt*2
     6 #define rson m + 1, r, rt*2+1
     7 #define X first
     8 #define Y second
     9 
    10 typedef pair<int,int> PII;
    11 typedef long long LL;
    12 typedef unsigned long long ULL;
    13 
    14 const int N = 1e3 + 10, Q = 1e5 + 10;
    15 
    16 struct Node {
    17   int op, x, y;
    18 } query[Q];
    19 
    20 vector<int> g[Q];
    21 
    22 int ans[Q], now;
    23 bitset<N> bs[N], tmp;
    24 
    25 void dfs(int k) {
    26   int op = query[k].op, x = query[k].x, y = query[k].y, flag = 0;
    27   if (op == 1) {
    28     --x; --y;
    29     if (bs[x][y] == 0) { flag = 1; now++; }
    30     bs[x][y] = 1;
    31   }
    32   else if (op == 2) {
    33     --x; --y;
    34     if (bs[x][y] == 1) { flag = 1; now--; }
    35     bs[x][y] = 0;
    36   }
    37   else if (op == 3) {
    38     --x;
    39     now -= bs[x].count();
    40     bs[x] = bs[x] ^ tmp;
    41     now += bs[x].count();
    42     flag = 1;
    43   }
    44 //  cout << k << ' ' << now << endl;
    45   ans[k] = now;
    46   for (int i = 0; i < (int)g[k].size(); i++) dfs(g[k][i]);
    47   if (!flag) return;
    48   if (op == 1) {
    49     bs[x][y] = 0;
    50     --now;
    51   }
    52   else if (op == 2) {
    53     bs[x][y] = 1;
    54     ++now;
    55   }
    56   else if (op == 3) {
    57     now -= bs[x].count();
    58     bs[x] = bs[x] ^ tmp;
    59     now += bs[x].count();
    60   }
    61 }
    62 
    63 int main() {
    64 //  freopen("case.in", "r", stdin);
    65   int n, m, q;
    66   cin >> n >> m >> q;
    67   for (int i = 0; i < m; i++) tmp[i] = 1;
    68   for (int i = 1; i <= q; i++) {
    69     scanf("%d%d", &query[i].op, &query[i].x);
    70     if (query[i].op < 3) scanf("%d", &query[i].y);
    71     if (query[i].op == 4) g[query[i].x].push_back(i);
    72     else g[i - 1].push_back(i);
    73   }
    74   dfs(0);
    75   for (int i = 1; i <= q; i++) printf("%d
    ", ans[i]);
    76   return 0;
    77 }
    代码君

    (2)数组在线,观察到一共只有1e5种不同的行的形态,用一个biset来记录所有可能的状态,记得pos(i,j)表示第i个操作的每一行对应每一行在biset的编号,然后有新的行的形态产生就塞到biset即可,复杂度O(nq)。

     

     1 /*zhen hao*/
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 
     5 #define lson l, m, rt*2
     6 #define rson m + 1, r, rt*2+1
     7 #define X first
     8 #define Y second
     9 
    10 typedef pair<int,int> PII;
    11 typedef long long LL;
    12 typedef unsigned long long ULL;
    13 
    14 const int N = 1e3 + 10, Q = 1e5 + 10;
    15 bitset<N> bs[Q], tmp;
    16 int pos[Q][N], res[Q];
    17 
    18 int main() {
    19 //  freopen("case.in", "r", stdin);
    20   int n, m, q, cnt = 0;
    21   scanf("%d%d%d", &n, &m, &q);
    22   for (int i = 1; i <= m; i++) tmp[i] = 1;
    23   for (int i = 1; i <= q; i++) {
    24     int op, x, y;
    25     scanf("%d%d", &op, &x);
    26     if (op == 4) {
    27       for (int j = 1; j <= n; j++) pos[i][j] = pos[x][j];
    28       res[i] = res[x];
    29     }
    30     else {
    31       for (int j = 1; j <= n; j++) pos[i][j] = pos[i - 1][j];
    32       res[i] = res[i - 1];
    33       int id = pos[i][x];
    34       if (op == 1) {
    35         scanf("%d", &y);
    36         if (bs[id][y] == 1) { printf("%d
    ", res[i]); continue; }
    37         bs[++cnt] = bs[id];
    38         bs[cnt][y] = 1;
    39         res[i]++;
    40         pos[i][x] = cnt;
    41       }
    42       if (op == 2) {
    43         scanf("%d", &y);
    44         if (bs[id][y] == 0) { printf("%d
    ", res[i]); continue; }
    45         bs[++cnt] = bs[id];
    46         bs[cnt][y] = 0;
    47         res[i]--;
    48         pos[i][x] = cnt;
    49       }
    50       if (op == 3) {
    51         bs[++cnt] = bs[id];
    52         res[i] -= bs[cnt].count();
    53         bs[cnt] = bs[cnt] ^ tmp;
    54         res[i] += bs[cnt].count();
    55         pos[i][x] = cnt;
    56       }
    57     }
    58     printf("%d
    ", res[i]);
    59   }
    60   return 0;
    61 }
    代码君

     

    题E E. Garlands

    题意:在n * m的网格上,给你k条链,一开始默认开,然后有两种操作(1)询问子矩阵的权值和,统计其中开的链的权值和,(2)将一条链置反。

    题解:感觉离线做比较好,虽说在线也不会超时。

    先将每一个ask操作(最多2000)记录下来,然后对于每个链维护一个res[i][j]表示i链在第j个ask里面的权值和,然后询问就可以做到O(k)。

     

     1 /*zhen hao*/
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 
     5 #define lson l, m, rt*2
     6 #define rson m + 1, r, rt*2+1
     7 #define X first
     8 #define Y second
     9 
    10 typedef pair<int,int> PII;
    11 typedef long long LL;
    12 typedef unsigned long long ULL;
    13 
    14 const int N = 2100, Q = 1e6 + 10;
    15 
    16 struct BIT {
    17   int n, m;
    18   LL C[N][N];
    19   inline int lowbit(int x) {
    20     return x & (-x);
    21   }
    22   void update(int x, int y, int d) {
    23     for (int i = x; i <= n; i += lowbit(i))
    24       for (int j = y; j <= m; j += lowbit(j))
    25         C[i][j] += d;
    26   }
    27   LL sum(int x, int y) {
    28     LL ret = 0;
    29     for (int i = x; i; i -= lowbit(i))
    30       for (int j = y; j; j -= lowbit(j))
    31         ret += C[i][j];
    32     return ret;
    33   }
    34 } T;
    35 
    36 struct Ask {
    37   int x1, y1, x2, y2;
    38 } A[N];
    39 
    40 struct Node {
    41   int x, y, z;
    42 };
    43 
    44 vector<Node> link[N];
    45 char s[Q][10];
    46 int sw[Q], flag[Q];
    47 LL ans[N][N];
    48 
    49 int main() {
    50 //  freopen("case.in", "r", stdin);
    51   int n, m, k, q;
    52   cin >> n >> m >> k;
    53   T.n = n;
    54   T.m = m;
    55   for (int i = 0; i < k; i++) {
    56     int sz, x, y, z;
    57     scanf("%d", &sz);
    58     while (sz--) {
    59       scanf("%d%d%d", &x, &y, &z);
    60       link[i].push_back((Node){x, y, z});
    61     }
    62   }
    63   scanf("%d", &q);
    64   int cnt = 0;
    65   for (int i = 0; i < q; i++) {
    66     scanf("%s", s[i]);
    67     if (s[i][0] == 'A') {
    68       scanf("%d%d%d%d", &A[cnt].x1, &A[cnt].y1, &A[cnt].x2, &A[cnt].y2);
    69       cnt++;
    70     }
    71     else {
    72       scanf("%d", sw + i);
    73       sw[i]--;
    74     }
    75   }
    76   for (int i = 0; i < k; i++) {
    77     for (int j = 0; j < (int)link[i].size(); j++) T.update(link[i][j].x, link[i][j].y, link[i][j].z);
    78     for (int j = 0; j < cnt; j++)
    79       ans[i][j] = T.sum(A[j].x2, A[j].y2) + T.sum(A[j].x1 - 1, A[j].y1 - 1) - T.sum(A[j].x1 - 1, A[j].y2) - T.sum(A[j].x2, A[j].y1 - 1);
    80     for (int j = 0; j < (int)link[i].size(); j++) T.update(link[i][j].x, link[i][j].y, -link[i][j].z);
    81   }
    82   cnt = 0;
    83   for (int i = 0; i < k; i++) flag[i] = 1;
    84   for (int i = 0; i < q; i++) {
    85     if (s[i][0] == 'A') {
    86       LL res = 0;
    87       for (int j = 0; j < k; j++) if (flag[j]) res += ans[j][cnt];
    88       printf("%I64d
    ", res);
    89       cnt++;
    90     }
    91     else {
    92       flag[sw[i]] ^= 1;
    93     }
    94   }
    95   return 0;
    96 }
    代码君
  • 相关阅读:
    MT【126】点对个数两题之二【图论】
    MT【125】四点共圆
    MT【124】利用柯西求最值
    MT【123】利用第一次的技巧
    MT【122】一个重要的不平凡的无穷级数
    MT【121】耐克数列的估计
    MT【120】保三角函数
    MT【119】关于恒成立的一道压轴题
    计算机视觉目标检测的框架与过程
    使用模板类导致error LNK2019: 无法解析的外部符号
  • 原文地址:https://www.cnblogs.com/zhenhao1/p/5796850.html
Copyright © 2011-2022 走看看