zoukankan      html  css  js  c++  java
  • 【BZOJ】1513: [POI2006]Tet-Tetris 3D

    题意

    (n(1 le n le 20000))个立方体((x, y, z)),依次落下。求所有立方体落下完了以后最高的高度。

    分析

    平面求最大值,平面更新最大值。

    题解

    二维线段树走起,由于不好自下往上更新而且发现更新的时候值是越来越大,所以我们可以在每一次更新的时候直接在走过的路径上更新一下最大值(or第二维线段树)即可。

    #include <bits/stdc++.h>
    using namespace std;
    inline int getint() {
    	int x=0, c=getchar();
    	for(; c<48||c>57; c=getchar());
    	for(; c>47&&c<58; x=x*10+c-48, c=getchar());
    	return x;
    }
    inline void U(int &a, int b) {
    	a=max(a, b);
    }
    const int N=2105;
    int n, m, q;
    struct T1 {
    	int w[N], tag[N];
    	void upd(int L, int R, int g, int l=1, int r=m, int x=1) {
    		U(w[x], g);
    		if(L<=l && r<=R) {
    			U(tag[x], g);
    			return;
    		}
    		int mid=(l+r)>>1;
    		if(L<=mid) {
    			upd(L, R, g, l, mid, x<<1);
    		}
    		if(mid<R) {
    			upd(L, R, g, mid+1, r, x<<1|1);
    		}
    	}
    	int ask(int L, int R, int l=1, int r=m, int x=1) {
    		if(L<=l && r<=R) {
    			return w[x];
    		}
    		int mid=(l+r)>>1, y=tag[x];
    		if(L<=mid) {
    			U(y, ask(L, R, l, mid, x<<1));
    		}
    		if(mid<R) {
    			U(y, ask(L, R, mid+1, r, x<<1|1));
    		}
    		return y;
    	}
    };
    struct T2 {
    	T1 w[N], tag[N];
    	void upd(int L, int R, int LL, int RR, int g, int l=1, int r=n, int x=1) {
    		w[x].upd(LL, RR, g);
    		if(L<=l && r<=R) {
    			tag[x].upd(LL, RR, g);
    			return;
    		}
    		int mid=(l+r)>>1;
    		if(L<=mid) {
    			upd(L, R, LL, RR, g, l, mid, x<<1);
    		}
    		if(mid<R) {
    			upd(L, R, LL, RR, g, mid+1, r, x<<1|1);
    		}
    	}
    	int ask(int L, int R, int LL, int RR, int l=1, int r=n, int x=1) {
    		if(L<=l && r<=R) {
    			return w[x].ask(LL, RR);
    		}
    		int mid=(l+r)>>1, y=tag[x].ask(LL, RR);
    		if(L<=mid) {
    			U(y, ask(L, R, LL, RR, l, mid, x<<1));
    		}
    		if(mid<R) {
    			U(y, ask(L, R, LL, RR, mid+1, r, x<<1|1));
    		}
    		return y;
    	}
    }t;
    
    int main() {
    	n=getint(), m=getint(), q=getint();
    	for(; q--; ) {
    		int d=getint(), s=getint(), w=getint(), x=getint(), y=getint();
    		++x, ++y;
    		t.upd(x, x+d-1, y, y+s-1, t.ask(x, x+d-1, y, y+s-1)+w);
    	}
    	printf("%d
    ", t.ask(1, n, 1, m));
    	return 0;
    }
  • 相关阅读:
    Oracle 日期总结
    JavaScript 获取文件名,后缀名
    JavaScript Array pop(),shift()函数
    JavaScript Array splice函数
    Oracle 创建表空间、临时表空间、创建用户并指定表空间、授权,删除用户及表空间
    eclipse debug调试java程序的九个技巧
    Oracle dos连接数据库基本操作
    Oracle 隐式游标 存储过程
    Oracle 修改表名
    Oracle 时间 MM-dd形式转换
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4985682.html
Copyright © 2011-2022 走看看