【bzoj4311】向量 线段树对时间分治+STL-vector维护凸包
题目描述
输入
输出
样例输入
5
1 3 3
1 1 4
3 3 3
2 1
3 3 3
样例输出
18
15
题解
线段树对时间分治+STL-vector维护凸包
首先需要知道向量 $(x_1,y_1)$ 和 $(x_2,y_2)$ 的点积(数量积)为 $x_1x_2+y_1y_2$ 。
问题转化为给出一堆 $x$ 、$y$ 和 $a$ 、$b$ ,求 $ax+by$ 的最大值。
设 $ax+by=c$ ,则整理可得 $y=-\frac abx+\frac cb$ ,要让 $c$ 最大即让截距最大。因此答案一定在上凸壳上取到。
由于有删除操作,因此使用线段树对时间分治,把一个向量出现的时间段分为线段树上的log个。
然后考虑怎么统计答案:由于平衡树维护凸包的时间复杂度时均摊的,因此不能在线段树上进行插入与恢复的操作。考虑到答案所在的每一段互不影响,因此可以对于线段树的每个节点维护凸包,查询时在每一段上进行二分,取最大值即为答案。
因此使用STL-vector,对于线段树的每个节点,维护上凸壳;查询时在其到线段树根节点的每个节点的凸包上二分,每个节点求出最优解后再取最大值即为答案。
这样做的时间复杂度时 $O(n\log ^2n)$ 。
存在一种更优的解法:对每个询问按照 $-\frac ab$ 从大到小排序,这样决策就是按 $x$ 单调不降的了。每个节点维护当前决策位置,统计时不断判断下一个是否比当前的优即可。
时间复杂度 $O(n\log n)$ ,然而跑不过 $O(n\log^2n)$ 什么鬼。。。
#include <cstdio>
#include <vector>
#include <algorithm>
#define N 200010
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
using namespace std;
typedef long long ll;
struct point
{
ll x , y;
point() {}
point(ll a , ll b) {x = a , y = b;}
point operator-(const point &a)const {return point(x - a.x , y - a.y);}
ll operator*(const point &a)const {return x * a.y - y * a.x;}
};
struct data
{
point p;
int l , r;
}a[N] , b[N] , c[N];
vector<point> v[N << 2];
int pos[N << 2] , val[N] , ta , tb , tc;
ll ans[N];
bool cmp1(const data &a , const data &b)
{
return a.p.x == b.p.x ? a.p.y < b.p.y : a.p.x < b.p.x;
}
bool cmp2(const data &a , const data &b)
{
return a.p * b.p < 0;
}
inline ll calc(point a , point b)
{
return a.x * b.x + a.y * b.y;
}
void insert(int b , int e , point p , int l , int r , int x)
{
if(b <= l && r <= e)
{
while(v[x].size() > 1 && (p - v[x][v[x].size() - 1]) * (p - v[x][v[x].size() - 2]) <= 0) v[x].pop_back();
v[x].push_back(p);
return;
}
int mid = (l + r) >> 1;
if(b <= mid) insert(b , e , p , lson);
if(e > mid) insert(b , e , p , rson);
}
ll query(int k , point p , int l , int r , int x)
{
ll ans = 0;
if(v[x].size())
{
while(pos[x] < (int)v[x].size() - 1 && calc(p , v[x][pos[x] + 1]) >= calc(p , v[x][pos[x]])) pos[x] ++ ;
ans = calc(p , v[x][pos[x]]);
}
if(l == r) return ans;
int mid = (l + r) >> 1;
if(k <= mid) return max(ans , query(k , p , lson));
else return max(ans , query(k , p , rson));
}
int main()
{
int n , i , opt , k;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%d" , &opt);
if(opt == 1) scanf("%lld%lld" , &a[i].p.x , &a[i].p.y) , a[i].l = i , a[i].r = n , val[++ta] = i;
else if(opt == 2) scanf("%d" , &k) , a[val[k]].r = i - 1 , a[i].r = -1;
else tc ++ , scanf("%lld%lld" , &c[tc].p.x , &c[tc].p.y) , c[tc].l = i;
}
for(i = 1 ; i <= n ; i ++ )
if(a[i].l)
b[++tb] = a[i];
sort(b + 1 , b + tb + 1 , cmp1);
for(i = 1 ; i <= tb ; i ++ ) insert(b[i].l , b[i].r , b[i].p , 1 , n , 1);
sort(c + 1 , c + tc + 1 , cmp2);
for(i = 1 ; i <= tc ; i ++ ) ans[c[i].l] = query(c[i].l , c[i].p , 1 , n , 1);
for(i = 1 ; i <= n ; i ++ )
if(!a[i].r)
printf("%lld\n" , ans[i]);
return 0;
}
【bzoj4311】向量 线段树对时间分治+STL-vector维护凸包的更多相关文章
- BZOJ_4311_向量_线段树按时间分治
BZOJ_4311_向量_CDQ分治+线段树按时间分治 Description 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 3.查询当前集合与(x,y) ...
- 【CF576E】Painting Edges 线段树按时间分治+并查集
[CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...
- 【BZOJ-4184 】 Shallot 线段树按时间分治 + 线性基
4184: shallot Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 356 Solved: 180[Submit][Status][Discu ...
- BZOJ_4025_二分图_线段树按时间分治+并查集
BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...
- BZOJ_4184_shallot_线段树按时间分治维护线性基
BZOJ_4184_shallot_线段树按时间分治维护线性基 Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻 ...
- Bipartite Checking CodeForces - 813F (线段树按时间分治)
大意: 动态添边, 询问是否是二分图. 算是个线段树按时间分治入门题, 并查集维护每个点到根的奇偶性即可. #include <iostream> #include <sstream ...
- BZOJ 1492 货币兑换 cdq分治或平衡树维护凸包
题意:链接 方法:cdq分治或平衡树维护凸包 解析: 这道题我拒绝写平衡树的题解,我仅仅想说splay不要写挂,insert边界条件不要忘.del点的时候不要脑抽d错.有想写平衡树的去看140142或 ...
- codevs 1080 线段树练习 CDQ分治
codevs 1080 线段树练习 http://codevs.cn/problem/1080/ 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 一行N个 ...
- BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector
题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...
随机推荐
- 20155336 《Java程序设计》实验二 (Java面向对象程序设计)实验报告
20155336 <Java程序设计>实验二 (Java面向对象程序设计)实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...
- 移除VS解决方案和TFS服务器的关系
有时候会遇到服务器IP服务器变更,甚至TFS服务器坏了,或者将项目重新上传至新的TFS区: 可以使用notepad之类的软件打开解决方案(.sln文件),删掉类似下面的部分: GlobalSectio ...
- easyui树动态加载参考
这篇文章是拷贝的,多谢原作者 友情连接:http://www.jb51.net/article/28771.htm var treeTitle = '选择列表'; var treeUrl = '../ ...
- [BZOJ1492][NOI2007]cash-[cdq分治]
Description 传送门 Solution 首先,最优情况一定是某一天把所有金券卖出或买入是最优的. 在金券一定的情况下,分散卖一定没有统一在最优的那天卖更优. 然后,我们假定在某一天卖,则在该 ...
- [arc062E]Building Cubes with AtCoDeer
Description 传送门 Solution 这道题直接暴力就好..毕竟只要枚举了前后两个瓷砖的方向和编号,其他瓷砖的颜色就是确定的了. 然而场上我的去重除了问题qaq. 我们钦定在立方体最前面的 ...
- 【LOJ4632】[PKUSC2018]真实排名
[LOJ4632][PKUSC2018]真实排名 题面 终于有题面啦!!! 题目描述 小 C 是某知名比赛的组织者,该比赛一共有 \(n\) 名选手参加,每个选手的成绩是一个非负整数,定义一个选手的排 ...
- 杂谈001:晨曦Dawn的重新连接
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 摘要: 我是晨曦,好久没有关注过我的博客了,整天都在乱糟糟的忙,叙述一下我消失的这段时间,然后我准备做几个专题 ...
- 基于ejabberd简单实现xmpp群聊离线消息
首先,xmpp服务器是基于ejabberd.离线消息模块是mod_interact,原地址地址:https://github.com/adamvduke/mod_interact: 修改后实现群聊离线 ...
- python全栈开发-面向对象-进阶
python_day_18 1,面向对象的三大特性是什么?继承,多态,封装2,什么是面向对象的新式类?什么是经典类?凡是继承object类都是新式类.凡是不继承object类都是经典类.3,面向对象为 ...
- Python爬虫:爬取美拍小姐姐视频
最近在写一个应用,需要收集微博上一些热门的视频,像这些小视频一般都来自秒拍,微拍,美拍和新浪视频,而且没有下载的选项,所以只能动脑想想办法了. 第一步 分析网页源码. 例如:http://video. ...