HDU 6638 - Snowy Smile

题意

给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大。

思路

  1. 先离散化纵坐标\(y\)的值
  2. 对\(n\)个点根据横坐标\(s\)进行排序
  3. 枚举横坐标,按顺序把点扔到线段树里,以离散化后\(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 线段树区间合并+暴力枚举的更多相关文章

  1. hdu 3397 Sequence operation (线段树 区间合并 多重标记)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ...

  2. HDU 5316——Magician——————【线段树区间合并区间最值】

    Magician Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  3. HDU 1540 Tunnel Warfare 线段树区间合并

    Tunnel Warfare 题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少 思路:一个节点的最大连续区间由(左儿子的最大的连续区间,右儿子的最大连续区 ...

  4. (简单) HDU 3308 LCIS,线段树+区间合并。

    Problem Description Given n integers. You have two operations: U A B: replace the Ath number by B. ( ...

  5. hdu 4453 约会安排(线段树区间合并)

    约会安排 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...

  6. hdu 3308 LCIS(线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3308 LCIS Time Limit: 6000/2000 MS (Java/Others)     ...

  7. hdu 1540 Tunnel Warfare 线段树 区间合并

    题意: 三个操作符 D x:摧毁第x个隧道 R x:修复上一个被摧毁的隧道,将摧毁的隧道入栈,修复就出栈 Q x:查询x所在的最长未摧毁隧道的区间长度. 1.如果当前区间全是未摧毁隧道,返回长度 2. ...

  8. HDU 4351 Digital root 线段树区间合并

    依然不是十分理解……待考虑…… #include <cstdio> #include <cstring> #include <cstdlib> #include & ...

  9. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

随机推荐

  1. javascript-object对象属性操作之Object.defineProperty

    一.基本用法简介 声明一个简单的对象,如下 var obj = { name: 'ldld' } 我们可以用Object.defineProperty来声明这个对象 var obj = {} Obje ...

  2. mariadb(三)查

    -查询基本使用(条件,排序,聚合函数,分组,分页) 1)创建一个表结构然后添加数据 create table baba (id int unsigned not null auto_increment ...

  3. Gogs 安装 - 本地安装,容器安装

    文章目录 安装 Gogs 本地安装 前提条件: 数据库 git 创建 git 用户 SSH 服务器 安装 升级 配置及运行 配置 运行 Gogs 服务 在线安装 Gogs 后台运行 gogs 通过 d ...

  4. 题解[SCOI2009]粉刷匠 难度:省选/NOI-

    Description windy有 N 条木板需要被粉刷.每条木板被分为 M 个格子.每个格子要被刷成红色或蓝色.windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色.每个格子最多 ...

  5. 逻辑回归提高阈值对p和r的影响

    这里我做了一个实验 也就是随着阈值的增大,precision增加或者不变,recall减少或者不变.

  6. Codeforces 433A (背包)

    题面 传送门 真是令人胃疼的题面 我不管,我要把苹果都给雪菜!(滑稽)(冬马党不要打我) 分析 突然感觉这题跟今年NOIP Day1T2有点像,都是根据数加减来构造背包,只不过这题是01背包而不是完全 ...

  7. BZOJ 3703: 昊昊的壮举之造福社会

    传送门 搜索,剪枝 首先可以二分答案迭代加深,假设要买 $p$ 台 那么肯定卖价格最小的 $p$ 台 再来个 $A*$ ,设搜到当前情况时,有 $waste$ 的钱一定要被浪费(其实就是某些学校剩下的 ...

  8. vue 页面切换从右侧切入效果

    1.将切换的页面用transition包裹 <div class="index-content"> <transition> <router-view ...

  9. AI-Tensorflow-神经网络优化算法-梯度下降算法-学习率

    记录内容来自<Tensorflow实战Google一书>及MOOC人工智能实践 http://www.icourse163.org/learn/PKU-1002536002?tid=100 ...

  10. Linux下svn回滚

    方法1: 用svn merge 1) 先 svn up,保证更新到最新的版本,如20: 2) 然后用 svn log ,查看历史修改,找出要恢复的版本,如10 .如果想要更详细的了解情况,可以使用sv ...