zoukankan      html  css  js  c++  java
  • 所谓的日常 #9

    div.2

    FZU 1492 地震预测

    嗯,n * n的运行时间是不可以通过的...

    事实上我们要对每个i,求出一个标号大于i且值小于A[i]的最大数,以及一个标号大于i且值大于A[i]的最小数。

    那么将(A[i],i)这个二元组排序后得到数组B,然后维护一个标号单调递减的栈 来解决上面的两个问题。时间复杂度O(nlogn) (排序的复杂度)。

    (>_<...嗯,这个题确实挂难了...起因是我把min看成了max,然后认为可以给大家做...不过还是有人通过了这个题好感动...恭喜@陈子民 同学 :) 

    用std::set也可以很方便的通过这个题,不过需要更多的C++知识啦,这里先不实现了。

    #include <stdio.h>
    #include <algorithm>
    
    const int N = 100000 + 5;
    int n,A[N];
    std::pair<int,int> B[N];
    int stack[N],top;
    int answer[N];
    
    void solve() {
        top = 0;
        for (int i = 0; i < n; ++ i) {
            int id = B[i].second;
            while (top > 0 && stack[top - 1] < id) -- top;
            if (top > 0) {
                answer[id] = std::min(answer[id],std::abs(A[stack[top - 1]] - A[id]));
            }
            stack[top++] = id;
        }
    }
    
    long long work() {
        for (int i = 0; i < n; ++ i) {
            B[i] = std::make_pair(A[i],i);
        }
        std::sort(B,B + n);
    
        for (int i = 0; i < n; ++ i) {
            answer[i] = (int)1e7;
        }
        answer[n - 1] = A[n - 1];
    
        solve();
        std::reverse(B,B + n);
        solve();
        long long ret = 0;
        for (int i = 0; i < n; ++ i) {
            ret += answer[i];
        }
        return ret;
    }
    
    int main() {
        while (scanf("%d",&n) == 1) {
            for (int i = 0; i < n; ++ i) {
                scanf("%d",A + i);
            }
            printf("%I64d
    ",work());
        }
    }
    View Code

    div.1

    FZU 2029 买票问题

    去吧STL...

    拎着一个set,一个map,以及一个queue,再加一个树状数组,就可以ac这个题了。时间复杂度(nlogn)。由于set/map的巨大常数,跑了2.7s。

    STL的话,在这里可以看 link

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <map>
     4 #include <set>
     5 #include <queue>
     6 #include <algorithm>
     7 
     8 const int N = 100000 + 5;
     9 int n;
    10 std::map<int,int> map;
    11 std::set<std::pair<int,int> > set;
    12 std::queue<int> que;
    13 int A[N],B[N];
    14 
    15 struct Fenwick {
    16     int C[N];
    17 
    18     void clear() {
    19         std::fill(C,C + n,0);
    20     }
    21 
    22     int modify(int p,int dt) {
    23         for (int i = p; i < n; i += ~i & i + 1) C[i] += dt;
    24     }
    25 
    26     int query(int p) {
    27         int ret = 0;
    28         for (int i = p; i >= 0; i -= ~i & i + 1) ret += C[i];
    29         return ret;
    30     }
    31 } bit;
    32 
    33 int main() {
    34     while (scanf("%d",&n) == 1) {
    35         bit.clear();
    36         map.clear();
    37         set.clear();
    38         while (!que.empty()) que.pop();
    39 
    40         for (int i = 0; i < n; ++ i) {
    41             char str[13];
    42             scanf("%s",str);
    43             if (strcmp(str,"add") == 0) {
    44                 int a,b;
    45                 scanf("%d%d",&a,&b);
    46                 A[i] = a;
    47                 B[i] = b;
    48                 map[a] = i;
    49                 set.insert(std::make_pair(b,i));
    50                 que.push(i);
    51                 bit.modify(i,1);
    52             } else if (strcmp(str,"pop") == 0) {
    53                 while (!que.empty() && map.find(A[que.front()]) == map.end()) que.pop();
    54                 if (!que.empty()) {
    55                     int id = que.front(); que.pop();
    56                     map.erase(A[id]);
    57                     set.erase(std::make_pair(B[id],id));
    58                     bit.modify(id,-1);
    59                 }
    60             } else if (strcmp(str,"leave") == 0) {
    61                 if (!set.empty()) {
    62                     int id = set.begin()->second;
    63                     set.erase(set.begin());
    64                     bit.modify(id,-1);
    65                     map.erase(A[id]);
    66                 }
    67             } else {
    68                 int x,y;
    69                 scanf("%d%d",&x,&y);
    70                 if (map.find(x) != map.end()) {
    71                     int id = map[x];
    72                     int cnt = bit.query(id - 1);
    73                     printf("%d
    ",cnt);
    74                     if (cnt > y) {
    75                         bit.modify(id,-1);
    76                         map.erase(A[id]);
    77                         set.erase(std::make_pair(B[id],id));
    78                     }
    79                 }
    80             }
    81         }
    82     }
    83 }
    View Code
  • 相关阅读:
    基础技术
    Luogu1438 无聊的数列(线段树)
    树状数组从入门到入土
    左偏树
    PA2014-Final Zarowki(堆)
    BZOJ1455罗马游戏
    【小米oj】 海盗分赃
    【小米oj】 最少交换次数
    【小米oj】 大胃王的烦恼
    【小米oj】 不一样的排序
  • 原文地址:https://www.cnblogs.com/zstuACM/p/5103694.html
Copyright © 2011-2022 走看看