zoukankan      html  css  js  c++  java
  • HDU5372——树状数组——Segment Game

    http://acm.hdu.edu.cn/showproblem.php?pid=5372

    /*
    要求有多少线段被现在加进去的线段完全覆盖,所求即左端点比当前加进去的线段大的减去右端点比当前加进去的线段大的,就是覆盖的线段树
    用两个树状数组来更新左端点和右端点的值
    跟求逆序数那道题目一样,进行排序,二分得到现在排序之后的位置,因为前面加进去的能更新后面的
    
    */
    /************************************************
    * Author        :Powatr
    * Created Time  :2015-8-14 14:15:49
    * File Name     :1004.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int MAXN = 5e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    
    int b[MAXN][3];
    int id[MAXN];
    int C1[MAXN], C2[MAXN];
    int a[MAXN];
    int m;
    
    int getid(int x)
    {
        return lower_bound(a, a + m, x) - a + 1;//使得从1开始
    }
    
    void add(int *tr, int x, int k)
    {
        while(x <= m){
            tr[x] += k;
            x += x&-x;
        }
    }
    
    int query(int *tr, int x)
    {
        int ret = 0;
        while( x > 0){
            ret += tr[x];
            x -= x&-x;
        }
        return ret;
    }
    
    int main()
    {
        int n;
        int cout = 0;
        while(~scanf("%d", &n)){
            printf("Case #%d:
    ", ++cout);
            m = 0;
            int cout1 = 0;
            for(int i = 1; i <= n; i++){
                scanf("%d%d", &b[i][0], &b[i][1]);
                if(b[i][0] == 0){
                    id[++cout1] = i;
                    b[i][2] = b[i][1] + cout1;
                    a[m++] = b[i][1];
                    a[m++] = b[i][2];
                }
            }
            sort(a, a + m);
            int l, r;
            m = unique(a, a + m) - a;
            memset(C1, 0, sizeof(C1));
            memset(C2, 0, sizeof(C2));
            for(int i = 1; i <= n; i++){
                if(b[i][0] == 0){
                    l = getid(b[i][1]);
                    r = getid(b[i][2]);
                    printf("%d
    ", query(C2, r) - query(C1, l-1));
                    add(C1, l, 1);
                    add(C2, r, 1);
                }
                else {
                    int p = id[b[i][1]];
                    l = getid(b[p][1]);
                    r = getid(b[p][2]);
                    add(C1, l, -1);
                    add(C2, r, -1);
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    Hash大法
    最小表示法
    KMP算法题集
    分块总结
    2018 雅礼国庆集训
    二分图总结
    贪心总结
    Tire树总结(模板+例题)
    工具类文章合集
    网文胡乱汇总
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4729927.html
Copyright © 2011-2022 走看看