• TOJ 4105 Lines Counting (树状数组)


    题意:给定N条线段,每条线段的两个端点L和R都是整数。然后给出M个询问,每次询问给定两个区间[L1,R1]和[L2,R2],问有多少条线段满足:L1≤L≤R1 , L2≤R≤R2 ?

    题解,采用离线做法,先将所有线段和询问区间全部保存。然后将每个询问[L1,R1][L2,R2]拆分成两个,L1-1, [L2,R2]和 R1,[L2,R2]。x, [L2,R2]表示起点 L <= x,终点 R满足 L2 <= R <= R2的线段条数,则每个询问的答案就是 R1,[L2,R2]的值 - L1-1, [L2,R2]的值。那么下面就需要查询x,[L2,R2]的值了。

    将所有线段按照起点排序;将所有新生成的询问按照x排序。之后是一遍扫描,对每个询问,循环直到线段起点L>x,否则树状数组中线段终点位置处值加1。此时计算树状数组第R2位置的前缀和减去L1-1位置处的前缀和即为答案。详见代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    #define N 100100
    struct Line{
        int s, t;
        bool operator < (const Line a) const {
            return s < a.s;
        }
    }p[N];
    struct Range{
        int s, id;
        Line t;
        bool operator < (const Range a) const {
            return s < a.s;
        }
    }rg[2*N];
    int v[N];
    int lb(int x){return x&-x;}
    void add(int id){
        while(id < N){
            v[id]++;
            id += lb(id);
        }
    }
    int get(int id){
        if(id == 0) return 0;
        return v[id]+get(id-lb(id));
    }
    int ans[N];
    int main(){
        int n, m, i, j;
        while(~scanf("%d", &n)){
            for(i = 0; i < n; i++) scanf("%d %d", &p[i].s, &p[i].t);
            scanf("%d", &m);
            int s1, t1, s2, t2, c = 0;
            for(i = 0; i < m; i++){
                scanf("%d %d %d %d", &s1, &t1, &s2, &t2);
                rg[c].s = s1-1;
                rg[c].t.s = s2, rg[c].t.t = t2;
                rg[c].id = c++;
    
                rg[c].s = t1;
                rg[c].t.s = s2, rg[c].t.t = t2;
                rg[c].id = c++;
            }
            sort(p, p+n);
            sort(rg, rg+c);
            memset(ans, 0,sizeof(ans));
            memset(v, 0, sizeof(v));
            for(int i = 0, j = 0; i < c; i++)
            {
                while(j < n && p[j].s <= rg[i].s)
                    add(p[j++].t);
                int tm = get(rg[i].t.t) - get(rg[i].t.s-1);
                if(rg[i].id&1) ans[rg[i].id/2] += tm;
                else ans[rg[i].id/2] -= tm;
            }
            for(int i = 0; i < m; i++) printf("%d
    ", ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    微分方程、动力系统与混沌导论 第1章 一阶方程[书摘]
    微分方程解耦
    指数输入时微分方程特解的求法
    例说信号与系统
    SVD分解的理解[转载]
    3D数学 ---- 矩阵和线性变换[转载]
    千里积于跬步——流,向量场,和微分方程[转载]
    微分方程——包络和奇解
    微分方程——基本概念和常微分方程的发展史
    sencha touch 入门学习资料大全
  • 原文地址:https://www.cnblogs.com/beisong/p/4492579.html
Copyright © 2020-2023  润新知