zoukankan      html  css  js  c++  java
  • E. Divide Square (树状数组,扫描线,思维)

    题目:传送门

    题意

    在左下角为(0, 0),右上角为 (1e6, 1e6) 的正方形中,有 n 条平行于 x 轴的线段和 m 条平行于 y 轴的线段,保证每条线段至少与正方形的一条边相交,且保证不存在两条线段在同一条线上,问你这些线段将正方形分成了几块.

    思路

    有两种情况,会增加一块:

    1.当线段与正方形的两条边相交时

    2.当两条线段相交时

    所以问题转化为求线段的交点个数,用扫描线+树状数组即可

    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define UI unsigned int
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF 0x3f3f3f3f
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    #define lb(x) ((x) & (-(x)))
    #define dbg(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
     
    const int N = 1e6 + 5;
     
    int n, m;
     
    struct note {
     
        int y, l, r;
     
    }a[N];
     
    struct node {
     
        int x, l, r;
     
    }b[N];
     
    vector < pair < int, int > > A[N], x[N];
     
    int t[N];
     
    void add(int pos, int x) {
     
        for(int i = pos; i < N; i += lb(i)) {
     
            t[i] += x;
     
        }
     
    }
     
    int query(int pos) {
     
        int ans = 0;
     
        for(int i = pos; i; i -= lb(i)) {
     
            ans += t[i];
     
        }
     
        return ans;
     
    }
     
    void solve() {
     
        scanf("%d %d", &n, &m);
     
        LL ans = 1LL;
     
        rep(i, 1, n) {
     
            scanf("%d %d %d", &a[i].y, &a[i].l, &a[i].r);
     
            A[a[i].l].pb(make(a[i].y, 1));
     
            A[a[i].r + 1].pb(make(a[i].y, -1));
     
            if(a[i].l == 0 && a[i].r == 1000000) ans++;
     
        }
     
        rep(i, 1, m) {
     
            scanf("%d %d %d", &b[i].x, &b[i].l, &b[i].r);
     
            x[b[i].x].pb(make(b[i].l, b[i].r));
     
            if(b[i].l == 0 && b[i].r == 1000000) ans++;
     
        }
     
        rep(i, 0, 1000000) {
     
            for(auto v : A[i]) add(v.fir, v.sec);
     
            for(auto v : x[i]) {
     
                int tmp1 = query(v.sec);
     
                int tmp2 = v.fir == 0 ? 0 : query(v.fir - 1);
     
                ans += tmp1 - tmp2;
     
            }
     
        }
     
        printf("%lld
    ", ans);
     
    }
     
     
    int main() {
     
    //    int _; scanf("%d", &_);
    //    while(_--) solve();
     
        solve();
     
        return 0;
    }
  • 相关阅读:
    C#中 类的多态
    字段与属性
    C# ASCII与字符串间相互转换
    TextBox控件常用方法总结
    使用hadoop mapreduce分析mongodb数据:(2)
    使用hadoop mapreduce分析mongodb数据:(1)
    Linux MPI集群配置
    VIM文本替换
    怎么解决python中TypeError: can't pickle instancemethod objects的这个错误
    LeetCode ZigZag problem
  • 原文地址:https://www.cnblogs.com/Willems/p/13617486.html
Copyright © 2011-2022 走看看