zoukankan      html  css  js  c++  java
  • 【洛谷】P4198 楼房重建

    题解

    我们转而维护每个点的斜率,显然一个楼房能被看见它就是一个前缀最大值,斜率比较为了节约精度可以用向量替代

    我们每个区间维护被看到的楼房的个数,和楼房的最大值,叶子节点在有楼房时,值为1

    那么考虑合并两个区间,左节点的所有能被看到的楼房还是能被看到,右边节点能看到的楼房的斜率需要大于左边节点所需要的斜率最大值
    为了找到这些我们去右节点的左右区间去找
    如果这个值(P)大于等于区间左边的最大值,那么这个值要在右边找
    如果小于的话,加上右边的大小,即(tr[u].cnt - tr[u << 1].cnt),然后递归到左边处理

    复杂度(O(n log^2 n))

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define MAXN 100005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 + c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    struct Point {
        int64 x,y;
        Point(int64 _x = 0,int64 _y = 0) {
    	x = _x;y = _y;
        }
        friend Point operator + (const Point &a,const Point &b) {
    	return Point(a.x + b.x,a.y + b.y);
        }
        friend Point operator - (const Point &a,const Point &b) {
    	return Point(a.x - b.x,a.y - b.y);
        }
        friend int64 operator * (const Point &a,const Point &b) {
    	return a.x * b.y - a.y * b.x;
        }
        friend bool operator < (const Point &a,const Point &b) {
    	return a * b > 0;
        }
        friend bool operator > (const Point &a,const Point &b) {
    	return a * b < 0;
        }
        friend bool operator == (const Point &a,const Point &b) {
    	return a * b == 0;
        }
        friend bool operator >= (const Point &a,const Point &b) {
    	return a > b || a == b;
        }
        friend bool operator <= (const Point &a,const Point &b) {
    	return a < b || a == b;
        }
    };
    struct node {
        int L,R,cnt;Point P;
    }tr[MAXN * 4];
    int N,M;
    
    void build(int u,int l,int r) {
        tr[u].L = l;tr[u].R = r;tr[u].cnt = 0;
        tr[u].P = Point(r,0);
        if(l == r) return;
        int mid = (l + r) >> 1;
        build(u << 1,l,mid);
        build(u << 1 | 1,mid + 1,r);
    }
    int Calc(int u,Point P) {
        if(tr[u].L == tr[u].R) return tr[u].P > P;
        if(P >= tr[u << 1].P) {
    	return Calc(u << 1 | 1,P);
        }
        else {
    	return Calc(u << 1,P) + tr[u].cnt - tr[u << 1].cnt;
        }
    }
    void Change(int u,int pos,int y) {
        if(tr[u].L == tr[u].R) {
    	tr[u].P = Point(pos,y);
    	if(!y) tr[u].cnt = 0;
    	else tr[u].cnt = 1;
    	return;
        }
        int mid = (tr[u].L + tr[u].R) >> 1;
        if(pos <= mid) Change(u << 1,pos,y);
        else Change(u << 1 | 1,pos,y);
        tr[u].P = max(tr[u << 1].P,tr[u << 1 | 1].P);
        tr[u].cnt = tr[u << 1].cnt + Calc(u << 1 | 1,tr[u << 1].P);
    }
    void Solve() {
        read(N);read(M);
        build(1,1,N);
        int x,y;
        for(int i = 1 ; i <= M ; ++i) {
    	read(x);read(y);
    	Change(1,x,y);
    	out(tr[1].cnt);enter;
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    
  • 相关阅读:
    crystal report 用存储过程的问题。
    新的开始—2014
    C#基础(二)——C#中的构造函数
    C#基础(一)——C#中反斜杠/n与/r的区别
    Html基础(一)
    yield关键字, default关键字, 别名关键字
    让 wpf tabcontrol 延缓初始化每个tab item content
    MVC,MVP,MVVM(补充)
    Focus scope in WPF
    Wpf ItemsControl 开启UI Virtualization 的条件
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9911322.html
Copyright © 2011-2022 走看看