zoukankan      html  css  js  c++  java
  • [hdu5372 Segment Game]树状数组

    题意:有两种操作:(1)插入线段,第i次插入的线段左边界为Li,长度为i (2)删除线段,删除第x次插入的线段。每次插入线段之前询问有多少条线段被它覆盖。

    思路:由于插入的线段长度是递增的,所以第i次插入的线段的长度比以前插入的所有线段都要长,从以前插入的线段里面任取一条,考虑其与当前线段的位置关系,主要有以下三种:

    图中,下方表示当前线段。注意到,只有被当前线段覆盖的线段,它的左右边界和当前线段的左右边界的相对位置是不同的。也就是说,查询有多少个线段的右端点小于等于该线段右端点,再查询有多少条线段左端点小于该线段的左端点, 两者之差就是答案。因为不符合要求的线段同时进入了前者和后者,而符合要求的答案只进入了前者。

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    //#pragma comment(linker, "/STACK:1024000000")
    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define X                   first
    #define Y                   second
    #define pb                  push_back
    #define mp                  make_pair
    #define all(a)              (a).begin(), (a).end()
    #define fillchar(a, x)      memset(a, x, sizeof(a))
    #define copy(a, b)          memcpy(a, b, sizeof(a))
    
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef unsigned long long ull;
    
    //#ifndef ONLINE_JUDGE
    void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);}
    void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
    void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1;
    while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
    void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
    void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
    void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
    //#endif
    template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
    template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
    template<typename T>
    void V2A(T a[],const vector<T>&b){for(int i=0;i<b.size();i++)a[i]=b[i];}
    template<typename T>
    void A2V(vector<T>&a,const T b[]){for(int i=0;i<a.size();i++)a[i]=b[i];}
    
    #if 0
    const double PI = acos(-1.0);
    const int INF = 1e9 + 7;
    const double EPS = 1e-8;
    #endif
    
    /* -------------------------------------------------------------------------------- */
    
    const int maxn = 4e5 + 7;
    
    int u[maxn], v[maxn], w[maxn], tot;
    pii rem[maxn];
    
    class TA {
        int C[maxn], n;
        inline int lowbit(int x) { return x & -x; }
    public:
        void init(int n) {
            this->n = n;
            for (int i = 1; i <= n; i ++) C[i] = 0;
        }
        void update(int p, int x) {
            while (p <= n) {
                C[p] += x;
                p += lowbit(p);
            }
        }
        int query(int p) {
            int ans = 0;
            while (p) {
                ans += C[p];
                p -= lowbit(p);
            }
            return ans;
        }
    };
    TA lta, rta;
    
    inline int find(int x) {
        return lower_bound(w, w + tot, x) - w + 1;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
    #endif // ONLINE_JUDGE
        int cas = 0, n;
        while (cin >> n) {
            tot = 0;
            int len = 1;
            for (int i = 0; i < n; i ++) {
                scanf("%d%d", u + i, v + i);
                if (u[i] == 0) {
                    rem[len] = mp(v[i], v[i] + len);
                    w[tot ++] = v[i];
                    w[tot ++] = v[i] + len ++;
                }
            }
            sort(w, w + tot);
            tot = unique(w, w + tot) - w;
            lta.init(tot);
            rta.init(tot);
            printf("Case #%d:
    ", ++ cas);
            len = 1;
            for (int i = 0; i < n; i ++) {
                if(u[i] == 1) {
                    pii buf = rem[v[i]];
                    int lid = find(buf.X), rid = find(buf.Y);
                    lta.update(lid, - 1);
                    rta.update(rid, - 1);
                }
                else {
                    int lid = find(v[i]), rid = find(v[i] + len ++);
                    printf("%d
    ", rta.query(rid) - lta.query(lid - 1));
                    lta.update(lid, 1);
                    rta.update(rid, 1);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    SQLServer查看死锁
    css图片叠加和底部定位
    vuejs
    如何优雅的使用vue+vux开发app -03
    ECMAScript 6 入门
    VUX 移动前端框架使用文档
    如何优雅的使用vue+vux开发app -02
    vuejs切换视图同时保持状态
    vuejs与服务器通信
    vuejs件同一个挂载点上切换组
  • 原文地址:https://www.cnblogs.com/jklongint/p/4723997.html
Copyright © 2011-2022 走看看