HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举
HDU 6638 - Snowy Smile
题意
给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大。
思路
- 先离散化纵坐标\(y\)的值
- 对\(n\)个点根据横坐标\(s\)进行排序
- 枚举横坐标,按顺序把点扔到线段树里,以离散化后\(y\)的\(id\)为下标\(pos\),存到线段树里
- 因为线段树可以在\(\log{n}\)的时间内插入数值,在\(O(1)\)的时间内查询当前区间最大子段和(线段树区间合并)
 \(node[rt].Max :\)当前区间最大子段和
 \(node[rt].lsum :\)当前区间从左端点开始最大连续子段和
 \(node[rt].rsum:\)当前区间从右端点开始最大连续子段和
 \(node[rt].sum:\)当前区间和
node[rt].Max = max(node[rt<<1].Max, node[rt<<1|1].Max);
node[rt].Max = max(node[rt].Max, node[rt<<1].rsum + node[rt<<1|1].lsum);
node[rt].lsum = max(node[rt<<1].lsum, node[rt<<1].sum + node[rt<<1|1].lsum);
node[rt].rsum = max(node[rt<<1|1].rsum, node[rt<<1|1].sum + node[rt<<1].rsum);
node[rt].sum = node[rt<<1].sum + node[rt<<1|1].sum;
然后就能愉快的解决这道题了,时间复杂度在\(O(n^2\log{n})\),枚举\(n^2\), 线段树插入\(\log{n}\)(今天下午做题一小时,自闭一下午也是没谁了,一直想不到做法,还是太菜了)
AC代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#define mes(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
const int inf = 1e9+7;
const int maxn = 2e3+10;
struct Node{
    ll Max, lsum, rsum, sum;
}node[maxn<<2];
struct A{
    int x, y;
    ll w;
    bool operator < (A const& b)const{
        return x > b.x;
    }
}a[maxn];
vector<int> y;
void build(int l, int r, int rt){
    node[rt].Max = node[rt].lsum = node[rt].rsum = node[rt].sum = 0;
    if(l == r)
        return;
    int mid = l+r>>1;
    build(l, mid, rt<<1);
    build(mid+1, r, rt<<1|1);
}
void pushup(int rt){
    node[rt].Max = max(node[rt<<1].Max, node[rt<<1|1].Max);
    node[rt].Max = max(node[rt].Max, node[rt<<1].rsum + node[rt<<1|1].lsum);
    node[rt].lsum = max(node[rt<<1].lsum, node[rt<<1].sum + node[rt<<1|1].lsum);
    node[rt].rsum = max(node[rt<<1|1].rsum, node[rt<<1|1].sum + node[rt<<1].rsum);
    node[rt].sum = node[rt<<1].sum + node[rt<<1|1].sum;
}
void update(int pos, ll c, int l, int r, int rt){
    if(l == r){
        node[rt].sum += c;
        if(node[rt].sum > 0){
            node[rt].lsum = node[rt].Max = node[rt].rsum = node[rt].sum;
        }
        else{
            node[rt].lsum = node[rt].Max = node[rt].rsum = 0;
        }
        return;
    }
    int mid = l+r>>1;
    if(pos <= mid)
        update(pos, c, l, mid, rt<<1);
    else
        update(pos, c, mid+1, r, rt<<1|1);
    pushup(rt);
}
int main(){
    int T, n;
    scanf("%d", &T);
    while(T--){
        y.clear();
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%d%d%lld", &a[i].x, &a[i].y, &a[i].w);
            y.push_back(a[i].y);
        }
        sort(y.begin(), y.end());
        y.erase(unique(y.begin(), y.end()), y.end());
        sort(a+1, a+1+n);
        ll ans = 0;
        a[0].x = inf;
        a[0].y = inf;
        for(int i = 1; i <= n; i++){
            if(a[i].x != a[i-1].x){		//相等的就跳过
                build(1, n, 1);
                for(int j = i; j <= n; j++){		//暴力枚举所有的横坐标x的左右区间
                    int id = lower_bound(y.begin(), y.end(), a[j].y) - y.begin() + 1;
                    update(id, a[j].w, 1, n, 1);
                    if(a[j].x == a[j+1].x && j != n) continue;	//相等的就跳过
                    ans = max(ans, node[1].Max);
                }
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}
HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举的更多相关文章
- hdu  3397  Sequence operation (线段树  区间合并  多重标记)
		链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ... 
- HDU 5316——Magician——————【线段树区间合并区间最值】
		Magician Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ... 
- HDU 1540 Tunnel Warfare 线段树区间合并
		Tunnel Warfare 题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少 思路:一个节点的最大连续区间由(左儿子的最大的连续区间,右儿子的最大连续区 ... 
- (简单)  HDU 3308  LCIS,线段树+区间合并。
		Problem Description Given n integers. You have two operations: U A B: replace the Ath number by B. ( ... 
- hdu 4453 约会安排(线段树区间合并)
		约会安排 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submis ... 
- hdu 3308 LCIS(线段树区间合并)
		题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3308 LCIS Time Limit: 6000/2000 MS (Java/Others) ... 
- hdu 1540 Tunnel Warfare 线段树 区间合并
		题意: 三个操作符 D x:摧毁第x个隧道 R x:修复上一个被摧毁的隧道,将摧毁的隧道入栈,修复就出栈 Q x:查询x所在的最长未摧毁隧道的区间长度. 1.如果当前区间全是未摧毁隧道,返回长度 2. ... 
- HDU 4351 Digital root 线段树区间合并
		依然不是十分理解……待考虑…… #include <cstdio> #include <cstring> #include <cstdlib> #include & ... 
- HDU 3911 线段树区间合并、异或取反操作
		题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ... 
随机推荐
- jenkins自动化打包报错:gradle: 未找到命令
			shell脚本如下: cd /home/wangju/gitProject/Automation echo "************************开始清理环境********** ... 
- StringTokenizer拆分字符串
			今天要做一个过滤特殊字符的需求, 看了下公司以前过滤特俗字符代码, 用的居然是 StringTokenizer, 完全不熟悉啊, 于是恶补了一下, 把StringTokenizer在JDK中的文档也翻 ... 
- How to resolve error “Failed to resolve: org.jetbrains.kotlin:kotlin-stdlib-jre7…” when building in Android Studio Ask Question
			//implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation & ... 
- 合并石子(区间DP)
			有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动相邻的2堆石子合并,合并花费为新合成的一堆石子的数量.求将这N堆石子合并成一堆的总花费最小. 区间DP思想:现在小区间进行DP得到最优解, ... 
- 安全体系建设-OWASP
			OWASP Checklist Spiders, Robots and Crawlers IG- Search Engine Discovery/Reconnaissance IG- Identify ... 
- phpcms列表分页ajax加载更多
			1.在phpcms\modules\content\index.php文件中添加以下函数: /*列表分页ajax加载更多*/ public function homeajaxlist() { if( ... 
- Aria2+WebUI+caddy搭建私有网盘
			Aria2安装 wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ar ... 
- Codeforces 1148C(思维)
			题面 给出一个长度为n的排列a,每次可以交换序列的第i个和第j个元素,当且仅当\(2 \times |i-j| \geq n\),求一种交换方案,让序列从小到大排好序 分析 重点是考虑我们怎么把第x个 ... 
- docker pull理解误区
			docker run 命令 如果local image中有对应 镜像+tag 不会从新拉取镜像 docker pull 会进行拉取 先进行镜像更改 [root@master01 ~]# docker ... 
- 【经典转载】关于Struts2的拦截器
			拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 ... 
