2019 Multi-University Training Contest 6 1005 Snowy Smile —— 线段树
This way
题意:
空间中有n个点,让你选择一个矩形覆盖一些点或者不覆盖任何点使得这个矩形中所有点的和最大。
题解:
虽然貌似它是个2000*2000的矩阵,但是它有的点只有2000个。所以我们先按照x轴排序,然后枚举左端点的同时枚举右端点,意思是固定左右端点,一定包括这两个点的最大子矩阵是多少。用线段树维护区间前缀和,然后查上面的最大前缀和-下面的最小前缀和,就像下图:
但是有一个很重要的剪枝,也就是在每次查询之前看看mx[1]-max(0ll,mi[1])是否小于等于ans,如果是的话就没必要往下做了。虽然不严谨,但是对于答案是不会有影响的。
#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std;
#define ll long long
const int N=2e3+5;
const ll inf=1e18;
int dis_x[N],dis_y[N];
ll mi[N*4],mx[N*4],flag[N*4],pre[N*4];
struct node
{int x,y;ll w;bool operator< (const node& a)const{return x<a.x;}
}p[N];
vector<node>have[N];
void push_down(int root)
{if(flag[root]==inf)return ;mi[root<<1]+=flag[root];mi[root<<1|1]+=flag[root];mx[root<<1]+=flag[root];mx[root<<1|1]+=flag[root];flag[root<<1]+=flag[root];flag[root<<1|1]+=flag[root];flag[root]=0;
}
void update(int l,int r,int root,int ql,int qr,ll v)
{if(l>=ql&&r<=qr){mi[root]+=v;mx[root]+=v;flag[root]+=v;return ;}push_down(root);int mid=l+r>>1;if(mid>=ql)update(l,mid,root<<1,ql,qr,v);if(mid<qr)update(mid+1,r,root<<1|1,ql,qr,v);mi[root]=min(mi[root<<1],mi[root<<1|1]);mx[root]=max(mx[root<<1],mx[root<<1|1]);
}
ll q_mi(int l,int r,int root,int ql,int qr)
{if(l>=ql&&r<=qr)return mi[root];push_down(root);int mid=l+r>>1;ll ans=inf;if(mid>=ql)ans=q_mi(l,mid,root<<1,ql,qr);if(mid<qr)ans=min(ans,q_mi(mid+1,r,root<<1|1,ql,qr));return ans;
}
ll q_mx(int l,int r,int root,int ql,int qr)
{if(l>=ql&&r<=qr)return mx[root];push_down(root);int mid=l+r>>1;ll ans=-inf;if(mid>=ql)ans=q_mx(l,mid,root<<1,ql,qr);if(mid<qr)ans=max(ans,q_mx(mid+1,r,root<<1|1,ql,qr));return ans;
}
int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d%lld",&p[i].x,&p[i].y,&p[i].w),dis_x[i]=p[i].x,dis_y[i]=p[i].y,have[i].clear();sort(dis_x+1,dis_x+1+n);sort(dis_y+1,dis_y+1+n);int all_x=unique(dis_x+1,dis_x+1+n)-dis_x-1;int all_y=unique(dis_y+1,dis_y+1+n)-dis_y-1;for(int i=1;i<=n;i++){p[i].x=lower_bound(dis_x+1,dis_x+1+all_x,p[i].x)-dis_x;p[i].y=lower_bound(dis_y+1,dis_y+1+all_y,p[i].y)-dis_y;have[p[i].x].push_back(p[i]);}sort(p+1,p+1+n);ll ans=0;for(int i=1;i<=n;i++){for(int j=0;j<=4*all_y;j++)mi[j]=0,mx[j]=0,flag[j]=0;for(int j=i;j<=n;j++){if(p[j].x==p[j-1].x&&p[j].y==p[j-1].y)continue;if(p[j].x!=p[j-1].x||j==i)for(auto v:have[p[j].x])update(1,all_y,1,v.y,all_y,v.w);q_mi(1,all_y,1,1,all_y);if(mx[1]-min(0ll,mi[1])<=ans)continue;int l=min(p[i].y,p[j].y),r=max(p[i].y,p[j].y);ll maxn=q_mx(1,all_y,1,r,all_y);ll minn=l-1>0?q_mi(1,all_y,1,1,l-1):0ll;if(minn<=0)ans=max(ans,maxn-minn);elseans=max(ans,maxn);}}printf("%lld\n",ans);}return 0;
}
/*
10
7
1 1 -1000000000
1 2 2000000000
1 3 3000000000
2 2 -2000000000
2 3 -2000000000
3 2 4000000000
3 3 5000000000
10
8
1 3 20
1 5 -30
1 7 10
5 5 60
5 2 -140
5 1 120
4 1 -130
2 8 -1118
1 3 40
1 5 -30
1 7 10
5 5 60
5 2 -140
5 1 120
4 1 -130
2 8 -111*/
2019 Multi-University Training Contest 6 1005 Snowy Smile —— 线段树相关推荐
- AtCoder Regular Contest 120 C - Swaps 2 线段树模拟
传送门 文章目录 题意: 思路: 题意: 给你两个序列a,ba,ba,b,每次可以执行一个操作:将a[i]a[i]a[i]与a[i+1]a[i+1]a[i+1]交换,且让交换后的a[i]+1,a[i+ ...
- HDU 5768 Lucky7(2016 Multi-University Training Contest 4 -1005)——中国剩余定理 + 容斥原理
[传送门](http://acm.hdu.edu.cn/showproblem.php?pid=5768) Lucky7 Time Limit: 2000/1000 MS (Java/Others) ...
- 2020 Multi-University Training Contest 6---- HDU--6836、Expectation(矩阵树)
题目链接 题面: 题意: 一棵树的权值定义为这棵树所有的边权的 按位与 的值. 给定一张图,问这张图的一棵生成树的权值的期望. 题解: 由于 按位与 在这个题中每一位独立.我们可以拆位来看. 对于第 ...
- [JZOJ6075]【GDOI2019模拟2019.3.20】桥【DP】【线段树】
Description N,M<=100000,S,T<=1e9 Solution 首先可以感受一下,我们把街道看成一行,那么只有给出的2n个点的纵坐标是有用的,于是我们可以将坐标离散化至 ...
- jzoj5986. 【WC2019模拟2019.1.4】立体几何题 (权值线段树)
传送门 题面 题解 不难看出每个点的大小为行列限制中较小的那一个(因为数据保证有解) 对于行的每个限制,能取到的个数是列里限制大于等于它的数的个数,同理,对于列是行里大于它的个数(这里没有等于,为了避 ...
- 2019.01.13 bzoj4137: [FJOI2015]火星商店问题(线段树分治+可持久化01trie)
传送门 题意:序列上有nnn个商店,有两种事件会发生: sss商店上进购标价为vvv的一个物品 求编号为[l,r][l,r][l,r]之间的位置买ddd天内新进购的所有物品与一个数xxx异或值的最大值 ...
- HDU 6638 [2019 Multi-University Training Contest 6]
Snowy Smile Problem Description There are n pirate chests buried in Byteland, labeled by 1,2,-,n. Th ...
- HDU 2019 Multi-University Training Contest 1 杭电2019多校联合训练赛 第一场 1001 Blank (6578)
HDU 2019 Multi-University Training Contest 1 杭电2019暑期多校集训第一场 1001 Blank (6578) Problem Description T ...
- 2019 Multi-University Training Contest 7 部分补题
2019 Multi-University Training Contest 7 部分补题 这场比赛三个人一起组队,比赛期间自己感觉并没有奉献多少东西,所以补题.而且总感觉比赛到后期很乏力(没力气那种 ...
- 2017 Multi-University Training Contest - Team 7:1005. Euler theorem(答案是(n+3)/2)
其他题目题解: 2017 Multi-University Training Contest - Team 7:1003. Color the chessboard 2017 Multi-Univer ...
最新文章
- redis 在 php 中的应用(事务 [ Transaction ] 篇)
- 阿里巴巴发布《2015移动安全漏洞年报》
- C语言面向对象编程(一):封装与继承
- win10家庭版没有device guard_普通用户选择哪个Win10系统版本?家庭版与专业版的对比介绍...
- Gentoo - ssh-agent配置
- java虚拟机参数优化_JAVA虚拟机JVM参数优化(2):垃圾收集算法选择
- leetcode 112 --- 二叉树根节点到叶子节点和为指定值的路径
- 论java中可变参数
- python中的type函数-python的type函数
- log nginx 显示时间_【日常小知识系列01】Nginx日志简述
- 转:Visio 2010 产品秘钥 亲测可用的
- python中的转义字符
- android 系统级闹铃,Android 设置系统闹铃和日历
- 集福啦!你想要的“福”这里都有~
- 初步认识地图布局和指北针 - SuperMap iDesktop 8C
- Python爬虫之bili站的正确打开方式
- 使用Atom编写以太坊智能合约
- <Zhuuu_ZZ>设计模式—面向接口编程
- 计算机网络协议分析 第三课 PAP,CHAP,PPPoE
- 京东数据中心主要基础设施系统(一)