• 2018 BIT 迎新赛


    啊这......总之就是先摸一摸以前的迎新赛,找找手感。

    网址http://codeforces.com/gym/102426

    A,忘了线性相关是啥,百度一波,然后根据以前的经验,大概高斯消元一波就行了吧。

    先消成倒三角,然后找一找有没有全0向量。有全零就代表线性相关。

    第一次交的时候莫名其妙的WA了...然后微调了几个地方莫名其妙就A了,太怪了。

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 
     5 const int N = 15;
     6 const double eps = 1e-10;
     7 
     8 int n, m;
     9 double a[N][N];
    10 
    11 inline double fabs(double x) {
    12     return (x < 0) ? (-x) : x;
    13 }
    14 
    15 inline bool work() {
    16     for(int i = 1; i < n; i++) {
    17         for(int j = i; j <= n; j++) {
    18             if(fabs(a[j][i]) > eps) {
    19                 // [j][i] != 0
    20                 std::swap(a[j], a[i]);
    21                 break;
    22             }
    23         }
    24         if(fabs(a[i][i]) < eps) {
    25             continue;
    26         }
    27         for(int j = i + 1; j <= n; j++) {
    28             if(fabs(a[j][i]) < eps) {
    29                 continue;
    30             }
    31             double x = a[j][i] / a[i][i];
    32             for(int k = i; k <= m; k++) {
    33                 a[j][k] -= a[i][k] * x;
    34             }
    35         }
    36     }
    37     for(int i = 1; i <= n; i++) {
    38         bool flag = false;
    39         for(int j = 1; j <= m; j++) {
    40             if(fabs(a[i][j]) > eps) {
    41                 flag = true;
    42                 break;
    43             }
    44         }
    45         if(!flag) {
    46             return true;
    47         }
    48     }
    49     return false;
    50 }
    51 
    52 inline void solve() {
    53 
    54     memset(a, 0, sizeof(a));
    55     scanf("%d%d", &n, &m);
    56     for(int i = 1; i <= n; i++) {
    57         for(int j = 1; j <= m; j++) {
    58             int x;
    59             scanf("%d", &x);
    60             a[i][j] = x;
    61         }
    62     }
    63 
    64     if(work()) {
    65         printf("YES
    ");
    66     }
    67     else {
    68         printf("NO
    ");
    69     }
    70 
    71     return;
    72 }
    73 
    74 int main() {
    75 
    76     int T;
    77     scanf("%d", &T);
    78     while(T--) {
    79         solve();
    80     }
    81 
    82     return 0;
    83 }
    AC代码

    B,仔细一看,傻逼打表题,1s不到就跑出来答案了。

    答案是93389411

    C,有点复杂,没啥技术含量,不想写先放着。

    D,cnm傻逼才会去写啊!

    E,啊这,一开始看到的时候,觉得蓝书上面应该见过类似的,结果不会做。想了半天,最后还是回到了二分上,想到我有没有办法先二分到哪个位置开头,再二分那一个串,结果就想到了从外部二分答案,啊这!秒切了。log²能过。

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 const int N = 100010;
     5 
     6 LL a[N];
     7 int n;
     8 
     9 template <typename T>
    10 inline T max(const T &a, const T &b) {
    11     return a > b ? a : b;
    12 }
    13 template <typename T>
    14 inline T min(const T &a, const T &b) {
    15     return a > b ? b : a;
    16 }
    17 
    18 inline LL cnt(LL x) {
    19     LL ans = 0;
    20     for(int i = 1; i <= n; i++) {
    21         int l = i, r = n, mid;
    22         while(l < r) {
    23             mid = (l + r + 1) >> 1;
    24             if(a[mid] - a[i - 1] < x) {
    25                 l = mid;
    26             }
    27             else {
    28                 r = mid - 1;
    29             }
    30         }
    31         ans += r - i + 1;
    32     }
    33     return ans;
    34 }
    35 
    36 int main() {
    37     LL l = 0x7fffffffffffffffll, r, mid, k;
    38     scanf("%d%lld", &n, &k);
    39     for(int i = 1; i <= n; i++) {
    40         scanf("%lld", &a[i]);
    41         l = min(l, a[i]);
    42         a[i] += a[i - 1];
    43     }
    44     r = a[n];
    45     while(l < r) {
    46         mid = (l + r + 1) >> 1;
    47         if(cnt(mid) >= k) {
    48             r = mid - 1;
    49         }
    50         else {
    51             l = mid;
    52         }
    53     }
    54     printf("%lld
    ", r);
    55     return 0;
    56 }
    AC代码

    写了半天,二分写法快忘了...

    F,好!见到一个水题,爽!

    直接把n * m个数排序,就是个阶梯状的东西,然后随便做做就行了。

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 const int N = 1e6 + 10;
     5 
     6 int n, m, t, v, a[N], b[N];
     7 
     8 int main() {
     9     scanf("%d%d%d", &n, &m, &v);
    10     t = n * m;
    11     for(int i = 1; i <= n; i++) {
    12         for(int j = 1; j <= m; j++) {
    13             scanf("%d", &a[(i - 1) * m + j]);
    14         }
    15     }
    16     std::sort(a + 1, a + t + 1);
    17     int h = a[t];
    18     for(int i = 1; i <= t; i++) {
    19         b[i] = a[i] - a[i - 1];
    20     }
    21     for(int i = t; i >= 1 && v; i--) {
    22         if(v >= b[i] * (t - i + 1)) {
    23             v -= b[i] * (t - i + 1);
    24             h -= b[i];
    25         }
    26         else {
    27             h -= v / (t - i + 1);
    28         }
    29     }
    30     printf("%d
    ", h);
    31     return 0;
    32 }
    AC代码

    G,好!位运算水题,秒了。

     1 #include <bits/stdc++.h>
     2 
     3 const int N = 20;
     4 
     5 int a[N], n = 11;
     6 char str[N];
     7 
     8 inline void out() {
     9     for(int i = 0; i < n; i++) {
    10         printf("%d ", a[i]);
    11     }
    12     puts("");
    13     return;
    14 }
    15 
    16 inline void add(int x) {
    17     for(int i = 0; i < n; i++) {
    18         if(x & (1 << i)) {
    19             a[i]++;
    20         }
    21     }
    22     out();
    23     return;
    24 }
    25 
    26 inline void del(int x) {
    27     int i = 0;
    28     while((1 << i) < x) {
    29         ++i;
    30     }
    31     while(!a[i] && i < n) {
    32         ++i;
    33     }
    34     if(i == n) {
    35         printf("ERROR!
    ");
    36     }
    37     else {
    38         int y = 1 << i;
    39         a[i]--;
    40         add(y - x);
    41     }
    42     return;
    43 }
    44 
    45 int main() {
    46     int T;
    47     scanf("%d", &T);
    48     while(T--) {
    49         int x;
    50         scanf("%s%d", str, &x);
    51         if(str[0] == 'f') {
    52             add(x);
    53         }
    54         else {
    55             del(x);
    56         }
    57     }
    58     return 0;
    59 }
    AC代码

    H

    先想到,如果子区间白学那么父区间也白学。然后考虑预处理出对于左端点 i ,到ans[i]是最小的白学区间。

    考虑到ans[i] ≤ ans[i + 1],可以从右向左加数字,同时用一个ans[i]指针从右向左单调移动。又考虑到ans[i]一定是三角形的一边,于是把那个指针从右向左移动,用一个值域数据结构来维护......挂了。到这里,不会做了。

    第二天,发现非白学串长度不会超过64,因为从最小往大加入,每次加入一个新数,如果想要不形成白学串,就要大于最大的两个之和。(感觉不是很严谨...)有了这个性质之后,直接从每个位置开始找log个,就是个log²了(还是用值域数据结构来维护有哪些数),为了速度我们选择树状数组,抱着试一试的心态写出来,结果切了。

    更具体的说,我们枚举左端点再枚举右端点,且这两个数一定是三角形的两边。于是第三条边就是(abs(a - b), a + b)这个范围内的了。

     1 #include <bits/stdc++.h>
     2 
     3 const int N = 100010;
     4 
     5 int a[N], n, ans[N], X[N], top, ta[N * 2];
     6 
     7 inline int abs(int x) {
     8     return (x < 0) ? (-x) : x;
     9 }
    10 
    11 inline void add(int i, int x) {
    12     for(; i <= top; i += i & (-i)) {
    13         ta[i] += x;
    14     }
    15 }
    16 inline int ask(int i) {
    17     int ans = 0;
    18     for(; i; i -= i & (-i)) {
    19         ans += ta[i];
    20     }
    21     return ans;
    22 }
    23 inline int ask(int l, int r) {
    24     if(l > r) return 0;
    25     return ask(r) - ask(l - 1);
    26 }
    27 
    28 inline void Main() {
    29     int m;
    30     scanf("%d%d", &n, &m);
    31     ans[n + 1] = n + 1;
    32     for(int i = 1; i <= n; i++) {
    33         scanf("%d", &a[i]);
    34         X[i] = a[i];
    35     }
    36     std::sort(X + 1, X + n + 1);
    37     top = std::unique(X + 1, X + n + 1) - X - 1;
    38     for(int i = 1; i <= n; i++) {
    39         a[i] = std::lower_bound(X + 1, X + top + 1, a[i]) - X;
    40     }
    41     // solve
    42     for(int i = n; i >= 1; i--) {
    43         ans[i] = n + 1;
    44         for(int j = i + 1; j <= n; j++) {
    45             int l = abs(X[a[i]] - X[a[j]]), r = X[a[i]] + X[a[j]];
    46             l = std::upper_bound(X + 1, X + top + 1, l) - X;
    47             r = std::lower_bound(X + 1, X + top + 1, r) - X - 1;
    48             if(ask(l, r)) {
    49                 ans[i] = j;
    50                 break;
    51             }
    52             if(j == ans[i + 1]) {
    53                 ans[i] = j;
    54                 break;
    55             }
    56             add(a[j], 1);
    57         }
    58         for(int j = i + 1; j < ans[i]; j++) {
    59             add(a[j], -1);
    60         }
    61     }
    62 
    63     int l, r;
    64     for(int i = 1; i <= m; i++) {
    65         scanf("%d%d", &l, &r);
    66         if(r >= ans[l]) {
    67             printf("yes
    ");
    68         }
    69         else {
    70             printf("no
    ");
    71         }
    72     }
    73     return;
    74 }
    75 
    76 int main() {
    77     int T;
    78     scanf("%d", &T);
    79     while(T--) {
    80         Main();
    81     }
    82     return 0;
    83 }
    AC代码

    I,搞不倒

    J,通过人数是最多的,然而...被long long坑了一次。

    仔细一研究,发现是个树形结构,一个树形DP就搞定了。

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 const int N = 200010;
     5 
     6 struct Edge {
     7     int nex, v;
     8 }edge[N]; int tp;
     9 
    10 int e[N], fa[N], n;
    11 LL f[N][2];
    12 
    13 inline void adde(int x, int y) {
    14     edge[++tp].v = y;
    15     edge[tp].nex = e[x];
    16     e[x] = tp;
    17 }
    18 
    19 void dfs(int x) {
    20     for(int i = e[x]; i; i = edge[i].nex) {
    21         int y = edge[i].v;
    22         dfs(y);
    23         f[x][0] += std::max(f[y][0], f[y][1]);
    24         f[x][1] += f[y][0];
    25     }
    26     f[x][1] += x;
    27     return;
    28 }
    29 
    30 int main() {
    31     scanf("%d", &n);
    32     for(int i = 1; i <= n; i++) {
    33         if(i & 1) {
    34             adde(n + 1, i);
    35         }
    36         else {
    37             adde(i / 2, i);
    38         }
    39     }
    40     dfs(n + 1);
    41     f[n + 1][1] -= n + 1;
    42     printf("%lld
    ", std::max(f[n + 1][0], f[n + 1][1]));
    43     return 0;
    44 }
    AC代码

    K,10个窗口,10次点击,瞧不起谁呢……

  • 相关阅读:
    #Kruskal算法 ——求最小生成树 ~20.8.17
    #最小生成树 #Prim算法 ——求最小生成树 ~20.8.15
    #Floyd #多源最短路 ~2020.08.15
    #Bellman-Ford最短路算法 #SPFA(spfa)算法 2020.08.14
    #单源最短路 #Dijkstra 学习心得 20.8.13
    #拓扑序列 学习心得 ~2020.08.13
    96.奇怪的汉诺塔
    95.费解的开关
    94.递归实现排列型枚举
    93.递归实现组合型枚举
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/13741559.html
Copyright © 2020-2023  润新知