HDOJ-1540 Tunnel Warfare(线段树+二分)

来源:互联网 发布:无法通过udp端口0通讯 编辑:程序博客网 时间:2024/06/07 04:44

当a村庄存在时,用二分找到1到a-1内核a村庄相连的最大村庄数目,再找到a+1,到n内和a村庄相连的最大村庄数目

#include <cstdio>#include <iostream>#include <vector>#include <algorithm>#include <cstring>#include <queue>#include <cmath>#include <stack>#define maxn 50005using namespace std;typedef long long ll;int num[maxn<<2], vis[maxn];stack<int> sta;void Update(int n, int l, int r, int s, int d){    if(l == r){        num[n] = d;        return ;    }    int mid = (l + r) >> 1;    if(s <= mid)     Update(n<<1, l, mid, s, d);    else     Update(n<<1|1, mid+1, r, s, d);    num[n] = num[n<<1] && num[n<<1|1];}void Query(int n, int l, int r, int L, int R, int &s){    if(l == L && R == r){        s = s && num[n];        return ;    }    int mid = (l + r) >> 1;    if(R <= mid)     Query(n<<1, l, mid, L, R, s);    else if(L > mid)     Query(n<<1|1, mid+1, r, L, R, s);    else{        Query(n<<1, l, mid, L, mid, s);        Query(n<<1|1, mid+1, r, mid+1, R, s);    }}int main(){//  freopen("in.txt", "r", stdin);    int n, m;    while(scanf("%d%d ", &n, &m) == 2){        while(!sta.empty())         sta.pop();        memset(vis, 0, sizeof(vis));        for(int i = 1; i <= (n<<2); i++)          num[i] = 1;        char ch;        int a;        while(m--){            scanf("%c ", &ch);            if(ch == 'D'){                scanf("%d ", &a);                vis[a] = 1;                Update(1, 1, n, a, 0);                sta.push(a);            }            else if(ch == 'R'){                int b = sta.top();                sta.pop();                vis[b] = 0;                Update(1, 1, n, b, 1);            }            else if(ch == 'Q'){                scanf("%d ", &a);                if(vis[a]){                    printf("%d\n", 0);                    continue;                }                int cnt = 1;                int l = 1, r = a;                if(r != 1){                while(l < r){                    int s = 1;                    int mid = (l + r) >> 1;                    Query(1, 1, n, mid, a-1, s);                    if(s)                      r = mid;                    else                     l = mid+1;                }                cnt += a - l;              }              if(l != n){                l = a + 1;                r = n + 1;                while(l < r){                    int s = 1;                    int mid = (l + r) >> 1;                    Query(1, 1, n, a+1, mid, s);                    if(s)                     l = mid + 1;                    else                     r = mid;                }                 cnt += l - a - 1;              }              printf("%d\n", cnt);            }        }    }    return 0;}
0 0
原创粉丝点击