zoukankan      html  css  js  c++  java
  • SPOJ Ada and Field (set,multiset)

    题意:给你T个例子,然后给出N,M,Q(2e9,2e9,1e5),即给出了一个(0,0)到(N,M)的矩形
    现在有Q次询问,0 a 表示在x轴的a处画一条平行于y轴的分割线。1 a 表示在y轴的a处画一条平行于x轴的平行线
    问每一次分割后最大的矩形面积为多少。
    思路:一开始拿到这道题我想到了线段树,然而...怎么更新边长(单点更新割点然后来维护区间最长段?)(当然用线段树是肯定能做的)
    看了网上题解之后 基本上都是使用的set 以及 multiset来做(因为2s多)。这里就当熟悉set的操作换一种来做吧。
    multiset可以保留多个重复的边,同时还自带二分排序。 multiset.erase(multiset.find(a)); 可以只消除集合中一个a,multiset.erase(a);则会删除集合中所有a.

    code:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<set>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn = 20000 + 10;
    set<ll> x, y;//分割点用set存储
    multiset<ll> lenx, leny;//边长用mulity来存储
    int main(){
        int T;
        ll n, m, q;
        scanf("%d", &T);
        while(T--){
            scanf("%lld%lld%lld", &n, &m, &q);
            x.clear(),y.clear();
            lenx.clear(),leny.clear();
            x.insert(0),x.insert(n),lenx.insert(n);
            y.insert(0),y.insert(m),leny.insert(m);
            set<ll>::iterator it;
            while(q--){
                ll  p;
                int op;
                scanf("%d%lld", &op, &p);
                if(op == 0 && x.count(p) == 0){
                    //如果切线p不存在,找到比p大的第一个位置,插入这个位置的左边
                    it = x.lower_bound(p);
                    //加入新分割出的右边的边
                    lenx.insert(*it - p);
                    //将长为len的消掉(对应的边)
                    int len = *it - *(--it);
                    lenx.erase(lenx.find(len));
                    //插入左边的边
                    lenx.insert(p - *it);
                    x.insert(p);
                }
                else if(op == 1 && y.count(p) == 0){
                    it = y.lower_bound(p);
                    leny.insert(*it - p);
                    int len = *it - *(--it);
                    leny.erase(leny.find(len));
                    leny.insert(p - *it);
                    y.insert(p);
                }
                it = lenx.end();
                ll ansx = *(--it);
                it = leny.end();
                ll ansy = *(--it);
                printf("%lld
    ", ansx * ansy);
            }
        }
        return 0;
    }
  • 相关阅读:
    CF293E Close Vertice
    [SCOI2016]幸运数字
    [NOI2003]逃学的小孩
    0302读后感
    1231递归下降语法分析
    1210-有穷自动机
    11.12 评论汇总
    1029语言文法
    0921 词法分析
    0909开启编译原理之路
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11352751.html
Copyright © 2011-2022 走看看