poj 2892 Tunnel Warfare(线段树#5/树状数组)

来源:互联网 发布:尼古丁口香糖 知乎 编辑:程序博客网 时间:2024/05/17 08:11

维护一个表,能够插入和删除,并且能够对某一点求前驱和后继。

方法一:线段树 422ms


#include <cstdio>#include <cstring>#include <stack> #include <set>#include <algorithm> #define N 50010using namespace std;  stack<int> st; int n, m;   int main(){                  char op[3];      int x;      //FILE * fp = fopen("in.txt", "r");       scanf( "%d %d", &n, &m);      set<int> v;       while (m--)      {            scanf( "%s", op);            if (op[0] == 'D')            {                      scanf( "%d", &x);                      st.push(x);                      v.insert(x);             }            else if (op[0] == 'R')            {                     int cc = st.top();                     st.pop();                     v.erase(cc);             }            else {                     scanf( "%d", &x);                     int ans;                      if (v.count(x) == 1)ans = 0;                     else if (v.size() == 0) ans = n;                      else                      {                          int l, r;                           set<int>::iterator it = v.upper_bound(x);                          if (it == v.end())r = n + 1, l = (*(--it)), ans = (r - l - 1);                          else if (it == v.begin())r = (*it), l = 0, ans = (r - l - 1);                          else {                                set<int>::iterator itt = (--it);                                it++;                                ans = (*it - *itt - 1);                          }                     }                      printf("%d", ans);                     if (m)puts("");             }      }     // getchar();       return 0;} 



方法二: STL  594ms


#include <cstdio>#include <cstring>#include <stack> #include <set>#include <algorithm> #define N 50010using namespace std;  stack<int> st; int n, m;   int main(){                  char op[3];      int x;      //FILE * fp = fopen("in.txt", "r");       scanf( "%d %d", &n, &m);      set<int> v;       while (m--)      {            scanf( "%s", op);            if (op[0] == 'D')            {                      scanf( "%d", &x);                      st.push(x);                      v.insert(x);             }            else if (op[0] == 'R')            {                     int cc = st.top();                     st.pop();                     v.erase(cc);             }            else {                     scanf( "%d", &x);                     int ans;                      if (v.count(x) == 1)ans = 0;                     else if (v.size() == 0) ans = n;                      else                      {                          int l, r;                           set<int>::iterator it = v.upper_bound(x);                          if (it == v.end())r = n + 1, l = (*(--it)), ans = (r - l - 1);                          else if (it == v.begin())r = (*it), l = 0, ans = (r - l - 1);                          else {                                set<int>::iterator itt = (--it);                                it++;                                ans = (*it - *itt - 1);                          }                     }                      printf("%d", ans);                     if (m)puts("");             }      }     // getchar();       return 0;} 


 法三:树状数组+二分查找  这个懒得写了

原创粉丝点击